Do1e

Do1e

github
email

Packaging Python Projects and Publishing with Poetry

This article is synchronized and updated to xLog by Mix Space
For the best browsing experience, it is recommended to visit the original link
https://www.do1e.cn/posts/code/poetry


Cause#

Currently maintaining these two Python projects:

I had been using setup.py for packaging, but when updating NJUlogin in November, I encountered the following message:

********************************************************************************
With Python 2.7 end-of-life, support for building universal wheels
(i.e., wheels that support both Python 2 and Python 3)
is being obviated.
Please discontinue using this option, or if you still need it,
file an issue with pypa/setuptools describing your use case.

By 2025-Aug-30, you need to update your project and remove deprecated calls
or your builds will no longer be supported.
********************************************************************************

Therefore, I decided to use the new pyproject.toml method for packaging. At that time, I quickly learned Poetry and adapted it for NJUlogin. Today, while updating mijia-api, I wanted to adapt it as well, but I found I forgot how to use it, so I’ll write a blog to document it. It seems I will be using Poetry more often to manage dependencies in the future.

Original packaging script ```powershell remove-item dist -force -recurse python setup.py sdist build python setup.py bdist_wheel --universal twine upload dist/* ```

Poetry#

The official website of Poetry positions itself as: Python packaging and dependency management made easy. It feels a bit like npm (if you have some understanding of nodejs), also managing dependency files via the command line.

However, Poetry is a bit long, so from now on, you will be called pop.

alias pop='poetry'
Set-Alias pop poetry

Installation#

Just check the documentation here: https://python-poetry.org/docs/#installation
I am using pipx for installation.

Initialize an existing project#

pop init

This will generate the following pyproject.toml file:

[tool.poetry]
name = "mijiaapi"
version = "0.0.0"
description = "A Python API for Xiaomi Mijia"
authors = ["Do1e <dpj.email@qq.com>"]
license = "GPLv3"
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.12"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

However, since my package contains uppercase letters, I need to change the name under [tool.poetry] and additionally manually add a packages entry, as well as some other configurations from setup.py:

2c2
< name = "mijiaapi"
---
> name = "mijiaAPI"
7a8,17
> homepage = "https://github.com/Do1e/mijia-api"
> repository = "https://github.com/Do1e/mijia-api"
> packages = [
>     {include = "mijiaAPI"}
> ]
> classifiers = [
>     "Programming Language :: Python :: 3",
>     "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
>     "Operating System :: OS Independent",
> ]

Create a Poetry virtual environment and install dependencies#

By default, it will create a virtual environment in ~/.cache/pypoetry, which can be modified using pop config. For more details, see the documentation here. I personally prefer to place it in the project directory:

# Configure the virtual environment to be placed in the project directory
pop config virtualenvs.in-project true
# Create and use the virtual environment
pop env use python
# If using in a conda environment, this step is not needed, it will directly use the existing conda environment
source .venv/bin/activate

After that, you can install dependencies one by one from requirements.txt. The following command will write the dependencies into the pyproject.toml file and generate poetry.lock:

pop add requests qrcode

One major advantage of Poetry is its ability to display dependencies in a tree structure:

pop show --tree
# qrcode 8.0 QR Code image generator
# └── colorama *
# requests 2.32.3 Python HTTP for Humans.
# ├── certifi >=2017.4.17
# ├── charset-normalizer >=2,<4
# ├── idna >=2.5,<4
# └── urllib3 >=1.21.1,<3

At this point, you can delete the original setup.py.

Package and publish#

The version can be dynamically specified using poetry-dynamic-versioning, so you don't have to modify the version number in pyproject.toml each time.

git tag v1.3.0
pop self add "poetry-dynamic-versioning[plugin]"
pop dynamic-versioning enable

Now you can simply use one command to build:

pop build

Unlike twine, which uses ~/.pypirc to save the pypi token, Poetry requires additional configuration:

pop config pypi-token.pypi pypi-xxxxxx

Then you can publish it!

pop publish
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.