Packaging and Publishing Python Libraries to PyPI: Goodbye setup.py, Hello Poetry

Python tutorial - IT technology blog
Python tutorial - IT technology blog

The Nightmare of “Code Reuse”

When I first started working on projects, I used to copy-paste logic from one tool to another. An automation script that started at around 200 lines would bloat to over 2,000 lines after a few months of maintenance. At that point, managing dependencies with a requirements.txt file became a complete disaster.

Every time I moved to a new machine, I struggled to fix version conflicts. I almost gave up when I tried to turn that code into a package installable via pip install. The convoluted configurations of setup.py and MANIFEST.in were a major barrier.

Why Does the Traditional Way Cause Headaches?

If you’ve ever tried packaging a library using the old method (Setuptools), you know how fragmented the process is:

  • Using requirements.txt to set up the environment.
  • Using setup.py or setup.cfg to define metadata.
  • Using MANIFEST.in just to manage non-technical files like README or License.
  • Facing “Dependency Hell” when libraries require incompatible cross-versions.

Forgetting to update the version in setup.py before uploading is a classic mistake. The result? You have to delete the old version, rename it, or bump the version and re-upload everything from scratch, which is a huge waste of time.

Modern Solutions: What’s the Best Choice?

The Python community has released several modern tools to clean up this mess:

  • Flit: Lightweight and perfect for simple libraries.
  • Pipenv: Great for virtual environment management, but packaging features are limited.
  • Poetry: My #1 choice for every project, from personal scripts to large enterprise systems.

Poetry – Everything in a Single Configuration File

Poetry consolidates everything into a pyproject.toml file. It manages dependencies strictly using a lock file while supporting building and publishing to PyPI with just a few simple commands.

Step 1: Installing Poetry Correctly

Avoid using pip install poetry to prevent polluting your system environment. Instead, use the official installation script:

curl -sSL https://install.python-poetry.org | python3 -

Once installed, type poetry --version to ensure everything is ready.

Step 2: Initializing the Project

To create a new library named itfromzero-utils, simply run:

poetry new itfromzero-utils

If you already have existing code, use the poetry init command inside your project directory. Poetry will ask a few questions about metadata and automatically generate a professional pyproject.toml file.

Step 3: Smart Dependency Management

Forget about manual text file editing. If you need the requests library, just type:

poetry add requests

Poetry will automatically find the appropriate version, update pyproject.toml, and generate a poetry.lock file. This lock file ensures your colleagues will have a 100% identical environment when they install it.

Step 4: Coding and Testing

Place your main logic functions in the itfromzero_utils/ directory. My experience is to manage the version only in the pyproject.toml file. To quickly bump the version, you can use the command poetry version patch (e.g., from 0.1.0 to 0.1.1).

To test your code in an isolated environment, use:

poetry run python main.py

Step 5: Publishing Your Library to the PyPI “Firing Line”

First, you need an account on PyPI. Create an API Token for security instead of using your personal password.

Configure the token for Poetry using the command:

poetry config pypi-token.pypi your-api-token-here

Finally, run the command that combines the build and publish steps into one:

poetry publish --build

This command will generate the .whl file and push it directly to the official Python repository in an instant.

Pro Tip: Avoid Cluttering PyPI

Don’t rush to publish the official version right away. Take advantage of TestPyPI – a sandbox environment where you can test freely.

poetry config repositories.testpypi https://test.pypi.org/legacy/
poetry publish -r testpypi --build

After checking that the package name looks good and there are no README formatting issues, then hit the real publish button.

A Few Notes to Avoid 403 Errors

  • Check the name: Search PyPI to see if someone has already taken your library name.
  • Gitignore: Always ignore the dist/ directory to avoid pushing heavy build files to GitHub.
  • Semantic Versioning: Follow the Major.Minor.Patch rule. PyPI is extremely_strict; you cannot overwrite an existing version.

Using Poetry saves me hours when managing complex Python projects. From someone who used to be afraid of packaging, I can now release a new version in under 2 minutes. If you encounter any difficulties during installation, feel free to leave a comment below!

Share: