Publish Python Packages
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.
- Repository URL: https://pypi.org/
- Simple Index: https://pypi.org/simple/
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.
- Navigate to https://pypi.org/ and log in.
- Go to your account settings and find the “API tokens” section.
- Generate a new token. You can scope it to a specific project if you wish.
- Copy the token and paste it into the
passwordfield in your~/.pypircfile. 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