Back to Home

Publishing a Python Package to PyPI with Poetry | Guide

Guide to Publishing a Python Package to the PyPI Repository Using the Poetry Tool. Describes Project Preparation Stages, API Token Setup, Artifact Building and Publishing. Covers Features of Working with Optional Dependencies and Project Structure Requirements.

How to Publish a Python Package to PyPI Using Poetry: Step by Step
Advertisement 728x90

Publishing a Python Package to PyPI: Automating the Process with Poetry

Publishing your own Python package to the PyPI repository is an essential step for developers who want to reuse their code. The Poetry tool greatly simplifies this process by handling dependencies and building artifacts. This guide covers project preparation, environment setup, and package publishing in detail, including working with API tokens and optional dependencies.

Account Setup and API Token Generation

The first step is to create an account on the official PyPI website. After registering, generate an API token for authentication during publishing. In your account dashboard, go to the API tokens section and click Generate API token. Specify a name for the token and select its scope. For new projects, an account-level token (Entire account) works well since you don't have any registered packages yet. Important: Copy the generated token immediately after creation—it won't be displayed again.

The generation process includes:

Google AdInline article slot
  • Logging in to your PyPI account
  • Navigating to the API tokens management section
  • Specifying the token name and scope
  • Confirming creation and saving the token value

Poetry will use this token for secure publishing without requiring your login and password. Store it securely, just like a password.

Initializing the Project with Poetry

Create the project root directory and set up a virtual environment:

python3 -m venv .venv
source .venv/bin/activate

Install Poetry via pip and run initialization:

Google AdInline article slot
pip install poetry
poetry init

In interactive mode, provide the basic parameters: package name, version, description, author, and supported Python version. The main fields in the generated pyproject.toml file:

  • name — unique package name in PyPI (must match the snake_case name of the code directory)
  • version — semantic version of the package
  • python — range of supported interpreter versions
  • readme — path to the description file
  • packages — pointer to the source code directory

After initialization, create a directory for the code (convert the name by replacing hyphens with underscores) and add the basic file structure.

Project Structure and Configuration

A typical project structure looks like this:

Google AdInline article slot
my-package/
├── LICENSE
├── poetry.lock
├── pyproject.toml
├── README.md
└── my_package/
    ├── __init__.py
    └── core.py

It's critically important to match the package name in pyproject.toml with the code directory name. For example, for name = "my-package", the directory must be named my_package. In the __init__.py file, it's recommended to import the main functions for ease of use.

Example implementation in core.py:

PREPEND_STR = 'prepend_'

def modify_str(string: str) -> str:
    return f'{PREPEND_STR}{string}'

Be sure to add a license file (preferably MIT) and a README.md with a description of the functionality. Lock the dependencies with poetry lock before publishing.

Building and Publishing the Package

Before uploading to the repository, build the artifacts:

poetry build

This command generates a source distribution (.tar.gz) and a wheel file (.whl) in the dist/ directory. Next, configure Poetry to use the API token:

poetry config pypi-token.pypi pypi-XXXXXXXX

Replace pypi-XXXXXXXX with your token. Now publish:

poetry publish

If successful, you'll see confirmation of the upload to PyPI. You can verify the publication by searching on the PyPI site or installing the package locally:

pip install my-package

Working with Optional Dependencies

To implement optional components (installed via pip install package[extra]), configure pyproject.toml like this:

[tool.poetry.dependencies]
python = "^3.10"
pydantic = {version=">=1.9", optional = true}

[tool.poetry.extras]
pydantic = ["pydantic"]

Here, the pydantic dependency is marked as optional with optional = true, and the extras section creates a pydantic group that includes this library. Users can install the extras with pip install my-package[pydantic].

Key Points

  • Strictly match the package name in pyproject.toml with the code directory name (hyphens → underscores)
  • Always include a license and a detailed README.md to build user trust
  • Use API tokens instead of login/password for secure publishing
  • For optional dependencies, properly configure the dependencies and extras sections
  • Before publishing, verify the build with poetry build

— Editorial Team

Advertisement 728x90

Read Next