Publishing a Python Package on PyPI with PEP 517/518: A Practical Guide
Learn how to publish a Python package on PyPI using the modern PEP 517/518 build system. This guide walks you through configuring pyproject.toml, building, validating, and uploading to Test PyPI before the final release.
21 Aug 2025, 03:45 UTC

Desired Outcome
Publish a fully‑reproducible Python package to PyPI that users can install with pip install your‑package. The package should include a source distribution (sdist) and a wheel (.whl) that passes PyPI’s metadata checks.
Prerequisites
- Python 3.9+ installed system‑wide or in a virtual environment.
- Administrative or user‑level access to create a PyPI account and generate an API token.
- Installed build tools:
pip install --upgrade build twine. - A project directory with at least one module, tests, and a
README.md.
Preparing the Project
1. Add a pyproject.toml
The pyproject.toml declares the build backend and its dependencies. The most common backend is setuptools.build_meta, which supports both legacy setup.py and modern pyproject.toml workflows.
[build-system]
requires = ["setuptools>=64.0.0", "wheel"]
build-backend = "setuptools.build_meta"
Place this file at the root of your repository. If you use poetry or another backend, replace the values accordingly.
2. Verify Build Dependencies
Missing or incompatible dependencies will cause python -m build to fail. Run:
python -m pip install --upgrade setuptools wheel
to ensure the backend can build your package.
Building the Package
Run the build command from the project root. It resolves the backend, installs any build‑time dependencies, and writes artifacts to a dist/ directory.
python -m build --wheel --no-isolation
Key options:
--wheelforces wheel creation; omit if you only need an sdist.--no-isolationruns the build in the current environment (useful for debugging).
After the command completes, you should see two files in dist/:
your_package‑0.1.0‑py3-none-any.whl
your_package‑0.1.0.tar.gz
Validating the Build
Before uploading, validate the artifacts with Twine. This checks metadata integrity and ensures the wheel will be accepted by PyPI.
twine check dist/*
Expected output: All checks passed. If errors appear, correct the pyproject.toml or setup.cfg metadata and rebuild.
Uploading to Test PyPI
Test PyPI is a sandbox that mirrors the production index. It allows you to install the package and verify behavior before the final release.
twine upload --repository testpypi dist/*
After upload, install the package from Test PyPI:
pip install --index-url https://test.pypi.org/simple/ your-package
Run your test suite or import the package in a REPL to confirm functionality. If issues arise, delete the distribution from Test PyPI via the web UI, fix the code, rebuild, and re‑upload.
Final Upload to PyPI
Once the package works on Test PyPI, upload to the main index. Use your PyPI API token for authentication. Store the token securely (e.g., ~/.pypirc or environment variable TWINE_USERNAME and TWINE_PASSWORD).
twine upload dist/*
After a successful upload, your package will be available at https://pypi.org/project/your-package/. Verify with:
pip install your-package
python -c "import your_package; print(your_package.__version__)"
Expected Checks & Recovery
- Build failure: Inspect the console for missing dependencies. Run
python -m pip checkto identify incompatible packages. - Twine validation errors: Usually indicate missing metadata (e.g.,
long_descriptionorauthor). Updatepyproject.tomlorsetup.cfgaccordingly. - Installation failure on Test PyPI: Common causes are missing compiled extensions or Python version incompatibilities. Ensure your wheel contains pre‑built binaries or provide a compatible sdist.
- Package not found after upload: Verify the package name and version are unique. If a name conflict occurs, rename the distribution or use a different version tag.
Recovery is straightforward: edit the source, rebuild, and re‑upload to Test PyPI first. Only push to the main index when the package passes all checks.
Limitations & Practical Checks
- PEP 517/518 does not support editable installs of source distributions on older Python versions (<3.9). Users may need to install from a wheel or a pre‑built binary.
- Custom build backends can introduce bugs; test them thoroughly in a CI pipeline before relying on them for production packages.
- Always keep your
pyproject.tomland build dependencies up to date to avoid deprecation warnings fromsetuptoolsorwheel.
To verify that your package is truly reproducible, run the build on a clean virtual environment:
python -m venv clean-env
source clean-env/bin/activate
pip install --upgrade pip build twine
python -m build --wheel
If the build succeeds, you can be confident that the package will build for end users.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.