This document outlines the necessary steps and configurations for publishing Python packages to the official Python Package Index (PyPI). Following these instructions will ensure your package is correctly uploaded and available for the public.

Server

All public Python packages should be published to PyPI. The server hosts the packages and provides the simple index that pip uses to discover and install them.

pypirc Configuration

To interact with PyPI, you need to configure a ~/.pypirc file. This file stores the repository details and your credentials. Reference for .pypirc file format Create or edit your ~/.pypirc file with the following content:

[distutils]
index-servers = pypi

[pypi]
repository: https://upload.pypi.org/legacy/
username: __token__

Obtaining Your pypirc Password

Your password for the pypirc file is an API token that you can generate from your PyPI account.

  1. Navigate to https://pypi.org/ and log in.
  2. Go to your account settings and find the “API tokens” section.
  3. Generate a new token. You can scope it to a specific project if you wish.
  4. Copy the token and paste it into the password field in your ~/.pypirc file. For the username, use __token__.

Twine Installation

twine is the recommended tool for securely uploading your packages to PyPI. You can install it using Homebrew or pip.

brew install twine or python3 -m pip install twine

Twine Usage

Once twine is installed and your ~/.pypirc file is configured, you can upload your package. The following command specifies the configuration file, the target repository, and the path to your package distribution file.

twine upload --repository pypi dist/*

Building Your Package

Before you can upload your package, you need to build the distribution files. The build process varies slightly depending on whether you are using a setup.py file or a pyproject.toml file.

Using setup.py

If your project uses a traditional setup.py file, run the following command to create a source distribution (sdist):

python3 ./setup.py sdist

Using pyproject.toml

For modern Python projects that use a pyproject.toml file, you’ll need the build package.

pyproject.toml file example:

[build-system]
requires = ["setuptools>=69.2.0", "build==1.3.0"]
build-backend = "setuptools.build_meta"

[project]
name = "your-package-name"
version = "0.0.1"
description = "package description"
authors = [{name = "username", email = "your-email@example.com"}]
readme = "README.md"
requires-python = ">=3.9"
dependencies = [
......
]

[tool.setuptools]
package-dir = {"" = "src"}

then build with :

python3 -m pip install build
python3 -m build

This will create the source and wheel files in a dist/ directory.

Handling Dependencies

Properly managing dependencies is crucial for ensuring that your package can be reliably installed and used. There are two main ways to specify dependencies for a Python project: abstract and concrete.

Abstract Dependencies (install_requires in setup.py or dependencies in pyproject.toml)

Abstract dependencies are used to specify the minimal set of packages required for your package to function. They are defined in the install_requires argument of your setup.py file or the dependencies list in your pyproject.toml. These should be as loose as possible to avoid conflicts with other packages.

When a user installs your package, pip will resolve and install these dependencies automatically.

Example in pyproject.toml:

[project]
name = "your-package-name"
version = "0.0.1"
...
dependencies = [
    "requests>=2.20.0",
    "numpy",
]

Concrete Dependencies (requirements.txt)

Concrete dependencies are used to create a reproducible environment, typically for development or testing. A requirements.txt file lists the exact versions of all packages (including dependencies of dependencies). This file is usually generated using pip freeze.

pip freeze > requirements.txt

A requirements.txt file is not used when your package is installed from PyPI. It is intended for developers who want to set up the exact environment used to develop the package.

To install dependencies from a requirements.txt file:

pip install -r requirements.txt