Poetry Packages
Let’s play with Packages and Libraries
References
Switch to Root Folder
cd /some/path/you/want
Create a new Package
poetry new mypackage
add some libraries
poetry add requests
… add some code …
cat << 'EOF' > mypackage/__init__.py
print("importing", __name__)
EOF
cat << 'EOF' > mypackage/main.py
print("importing", __name__)
def test1():
print("test1")
def test2(name: str):
print("hello", name)
def test3(name: str, age:int):
print(f"Hello {name} at age {age}")
if __name__ == "__main__":
print("This is a Library or Package. You should import it into your Code and not run it directly ...")
EOF
Build Package
poetry build
List Tree
(mypackage-py3.11) stoege@host:~/git/demo/mypackage> tree
.
├── README.md
├── dist
│ ├── mypackage-0.1.0-py3-none-any.whl
│ └── mypackage-0.1.0.tar.gz
├── mypackage
│ ├── __init__.py
│ └── main.py
├── poetry.lock
├── pyproject.toml
└── tests
└── __init__.py
4 directories, 8 files
you have a package called “mypackage-0.1.0” created. As ’tar.gz and ‘.whl’ File
Demo App bauen
now, we need a small app where we can install and test this Library.
Back to Root Folder
cd /some/path/you/want
create New App
poetry new myapp
cd myapp
poetry shell
add Fastapi (for example)
poetry add fastapi
Import our Library
poetry add ../mypackage/
(mypackage-py3.11) stoege@host:~/git/demo/myapp> poetry add ../mypackage/
Configuration file exists at /Users/stoege/Library/Preferences/pypoetry, reusing this directory.
Updating dependencies
Resolving dependencies... (0.1s)
Package operations: 14 installs, 0 updates, 0 removals
• Installing idna (3.4)
• Installing sniffio (1.3.0)
• Installing typing-extensions (4.7.1)
• Installing annotated-types (0.5.0)
• Installing anyio (3.7.1)
• Installing certifi (2023.7.22)
• Installing charset-normalizer (3.2.0)
• Installing pydantic-core (2.6.3)
• Installing urllib3 (2.0.4)
• Installing pydantic (2.3.0)
• Installing requests (2.31.0)
• Installing starlette (0.27.0)
• Installing fastapi (0.101.1)
• Installing mypackage (0.1.0 /Users/stoege/git/demo/mypackage)
-> mypackage v0.1.0 got installed as well !
Tree
(myapp-py3.11) stoege@host:~/git/demo/myapp> tree
.
├── README.md
├── myapp
│ └── __init__.py
├── poetry.lock
├── pyproject.toml
└── tests
└── __init__.py
that’s fine, but there is a hidden Folder “.venv”
Tree -a
(myapp-py3.11) stoege@host:~/git/demo/myapp> tree -a |more
.
├── .venv
│ ├── .gitignore
│ ├── bin
│ │ ├── activate
│ │ ├── activate.csh
│ │ ├── activate.fish
│ │ ├── activate.nu
│ │ ├── activate.ps1
│ │ ├── activate_this.py
│ │ ├── normalizer
│ │ ├── pip
│ │ ├── pip-3.11
│ │ ├── pip3
│ │ ├── pip3.11
│ │ ├── python -> /usr/local/opt/python@3.11/bin/python3.11
│ │ ├── python3 -> python
│ │ ├── python3.11 -> python
│ │ ├── wheel
│ │ ├── wheel-3.11
│ │ ├── wheel3
│ │ └── wheel3.11
│ ├── lib
│ │ └── python3.11
│ │ └── site-packages
│ │ ├── __pycache__
│ │ │ └── _virtualenv.cpython-311.pyc
│ │ ├── _distutils_hack
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ └── __init__.cpython-311.pyc
--- snip ---
│ │ ├── mypackage
│ │ │ ├── __init__.py
│ │ │ └── main.py
│ │ ├── mypackage-0.1.0.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── WHEEL
│ │ │ └── direct_url.json
--- snip ---
pyproject.toml
(myapp-py3.11) stoege@host:~/git/demo/myapp> cat pyproject.toml
[tool.poetry]
name = "myapp"
version = "0.1.0"
description = ""
authors = ["Daniel Stocker <blog@stoege.net>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.11"
mypackage = {path = "../mypackage"}
fastapi = "^0.101.1"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
-> mypackage got added to pyproject.toml
List Apps
(myapp-py3.11) stoege@host:~/git/demo/myapp> poetry show
annotated-types 0.5.0 Reusable constraint types to use with typing.Annotated
anyio 3.7.1 High level compatibility layer for multiple asynchronous event loop implementations
certifi 2023.7.22 Python package for providing Mozilla's CA Bundle.
charset-normalizer 3.2.0 The Real First Universal Charset Detector. Open, modern and actively maintained alterna...
fastapi 0.101.1 FastAPI framework, high performance, easy to learn, fast to code, ready for production
idna 3.4 Internationalized Domain Names in Applications (IDNA)
mypackage 0.1.0 ../mypackage
pydantic 2.3.0 Data validation using Python type hints
pydantic-core 2.6.3
requests 2.31.0 Python HTTP for Humans.
sniffio 1.3.0 Sniff out which async library your code is running under
starlette 0.27.0 The little ASGI library that shines.
typing-extensions 4.7.1 Backported and Experimental Type Hints for Python 3.7+
urllib3 2.0.4 HTTP library with thread-safe connection pooling, file post, and more.
add Code
cat << 'EOF' > myapp/__init__.py
print("importing", __name__)
EOF
cat << 'EOF' > myapp/main.py
print("importing", __name__)
import myapp
from mypackage.main import test1
import mypackage.main as gugus
import mypackage.main
def main():
print("run main function")
test1()
gugus.test2(name="Hans")
mypackage.main.test3(name="Hans", age="25")
if __name__ == "__main__":
print("run main code")
main()
EOF
Run App
(myapp-py3.11) stoege@host:~/git/demo/myapp> python myapp/main.py
importing __main__
importing myapp
importing mypackage
importing mypackage.main
run main code
run main function
test1
hello Hans
Hello Hans at age 25
Update pyproject
[tool.poetry.scripts]
myapp = 'myapp.main:main'
Poetry install
poetry install
Run Shortcut
(myapp-py3.11) stoege@host:~/git/demo/myapp> myapp
importing myapp
importing myapp.main
importing mypackage
importing mypackage.main
run main function
test1
hello Hans
Hello Hans at age 25
Include as an editable external package
- build another app, myapp2 for example
- don’t add the package via ‘poetry add ../mypack…’
import as editable package
[tool.poetry.dependencies]
python = "^3.11"
fastapi = "^0.101.1"
mypackage = { path = "../mypackage/", develop = true }
-> add mypackage here
Add Code
cat << 'EOF' > myapp2/__init__.py
print("importing", __name__)
EOF
cat << 'EOF' > myapp2/main.py
print("importing", __name__)
import myapp
from mypackage.main import test1
import mypackage.main as gugus
import mypackage.main
def main():
print("run main function")
test1()
gugus.test2(name="Hans")
mypackage.main.test3(name="Hans", age="25")
if __name__ == "__main__":
print("run main code")
main()
EOF
Run Code
(myapp2-py3.11) stoege@host:~/git/demo/myapp2> python myapp2/main.py
importing __main__
importing myapp2
importing mypackage
importing mypackage.main
run main code
run main function
test1
hello Hans
Hello Hans at age 25
Update Package
replace the function “test1” in the mypackage/main.py File
def test1():
print("test 12345")
Run Code
(myapp2-py3.11) stoege@host:~/git/demo/myapp2> python myapp2/main.py
importing __main__
importing myapp2
importing mypackage
importing mypackage.main
run main code
run main function
test 12345
hello Hans
Hello Hans at age 25
-> can you see the “test 12345” ?
let’s play the code on first “myapp” again:
(myapp-py3.11) stoege@host:~/git/demo/myapp> python myapp/main.py
importing __main__
importing myapp
importing mypackage
importing mypackage.main
run main code
run main function
test1
hello Hans
Hello Hans at age 25
Update mypackage
we have modified the package and need to rebuild it. Update Version
update poetry
[tool.poetry]
name = "mypackage"
version = "0.1.2"
-> update version to 0.1.2
build again
stoege@host:~/git/demo/mypackage> poetry build
Building mypackage (0.1.2)
- Building sdist
- Built mypackage-0.1.2.tar.gz
- Building wheel
- Built mypackage-0.1.2-py3-none-any.whl
stoege@play243:~/git/demo/mypackage>
Update Package in “myapp”
(myapp-py3.11) stoege@host:~/git/demo/myapp> poetry update
Updating dependencies
Resolving dependencies... (0.9s)
Package operations: 0 installs, 1 update, 0 removals
• Downgrading mypackage (0.1.1 /Users/stoege/git/demo/mypackage -> 0.1.2 /Users/stoege/git/demo/mypackage)
Writing lock file
Run again
(myapp-py3.11) stoege@host:~/git/demo/myapp> myapp
importing myapp
importing myapp.main
importing mypackage
importing mypackage.main
run main function
test 12345
hello Hans
Hello Hans at age 25
-> and we also got ’test 12345’
how to Publish Package to test.pypi.org
create account on plattform
- https://test.pypi.org/
- confirm mail
- login
- create 2fa
- go to setting, api-token
- add api-token, note it down (you won’t see it again …)
build Package
python3 -m pip install --upgrade twine
package pushen
python3 -m twine upload --repository testpypi dist/*
username: __ token __
password: pypy-xXxXxX – your token – xXxXxX
packages on test.pypi.org
Install on your Test Project
pip install -i https://test.pypi.org/simple/ stolib
TODO
demo app2 bauen
add test.pypi.org to pyproject.org
poetry source add --priority=primary test https://test.pypi.org/simple/
cat pyproject.toml
--- snip ---
[[tool.poetry.source]]
name = "test"
url = "https://test.pypi.org/simple/"
priority = "primary"
--- snip ---
show Sources
poetry source show
name : test
url : https://test.pypi.org/simple/
priority : primary
library adden von test.pypi.org
poetry add stolib
Any Comments ?
sha256: cc7b26661a3a0f03ee55fc47b54f2f9acf15d51aff35e263c9e01ee593764055