Python Packaging and Distribution with build and twine
A modern guide to packaging your Python project and publishing it to the Python Package Index (PyPI) using the standard `build` and `twine` tools.
So you've written a useful Python library. How do you share it with the world so that others can easily install it with a simple pip install your-package
? The answer is to package it and upload it to the Python Package Index (PyPI).
In the past, this process involved a setup.py
file and could be confusing. Today, the modern, standardized process is much simpler and relies on two key tools: build
and twine
.
This guide assumes you have a standard project structure with a pyproject.toml
file.
Step 1: Configure Your pyproject.toml
Your pyproject.toml
file is the heart of your package's configuration. It contains all the metadata that PyPI will display about your project. Ensure the [project]
section is filled out completely.
[project]
name = "my-cool-package"
version = "0.1.0"
description = "A short description of my cool package."
readme = "README.md" # Important for PyPI display
requires-python = ">=3.8"
license = { text = "MIT" }
authors = [
{ name = "Your Name", email = "your@email.com" },
]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
dependencies = [
"requests>=2.28",
]
[project.urls]
Homepage = "https://github.com/your-username/my-cool-package"
"Bug Tracker" = "https://github.com/your-username/my-cool-package/issues"
readme
: Specifies the file that will be used as the long description on PyPI.classifiers
: These are important tags that help users find your package.
Step 2: Install build
and twine
These are the tools you'll use to create the distribution packages and upload them.
pip install build twine
Step 3: Build the Distribution Archives
Now, from the root of your project (the same directory as pyproject.toml
), run the build
command:
python -m build
This command will do two things:
- It will create a
build/
directory for intermediate files. - It will create a
dist/
directory containing the final distribution packages.
Inside the dist/
directory, you will find two important files:
my_cool_package-0.1.0-py3-none-any.whl
: This is a wheel file. It's a pre-built, binary distribution format that is faster for end-users to install.my_cool_package-0.1.0.tar.gz
: This is a source archive (sdist). It contains your raw source code and is used as a fallback.
You should always upload both.
Step 4: Upload to PyPI
This is where twine
comes in. It's a secure tool for uploading your packages to PyPI.
First, you'll need a PyPI account. If you don't have one, register at pypi.org. It's also highly recommended to enable two-factor authentication (2FA) on your account.
Uploading to TestPyPI (Recommended for your first time):
TestPyPI is a separate instance of the package index where you can test the full distribution process without affecting the real index.
python -m twine upload --repository testpypi dist/*
Twine will prompt you for your username and password. For the password, you should generate an API token from your TestPyPI account settings and use that instead of your actual password.
Uploading to the real PyPI:
Once you've confirmed everything looks good on TestPyPI, you can upload to the official index.
python -m twine upload dist/*
Again, Twine will prompt for your credentials. Use your real PyPI username and an API token generated from your pypi.org account.
Step 5: Verify and Install
Congratulations! Your package is now live. You can navigate to https://pypi.org/project/my-cool-package/
to see your project's page.
Now, you (and anyone else in the world) can install it:
pip install my-cool-package
Automating with a Makefile
To make this process repeatable, you can create a simple Makefile
in your project root:
.PHONY: clean build publish
clean:
rm -rf build dist *.egg-info
build:
python -m build
publish:
python -m twine upload dist/*
publish-test:
python -m twine upload --repository testpypi dist/*
Now, your workflow becomes a series of simple commands:
make clean
make build
make publish-test
(to test)make publish
(for real)
Conclusion
Packaging and distributing Python code has never been more straightforward. By using a well-configured pyproject.toml
and the standard build
and twine
tools, you can easily share your work with the global Python community. This standardized process ensures that your package is easy to maintain and for others to install and use.