Publish a Python package flashcards
Turn your Python code into a package anyone can pip install, built and released the modern way.
Beginner friendly, starts from zero
0
Publish a Python package at a glance
Publishing a package puts your Python code on PyPI so anyone can install it with pip install.
Like publishing a book: give it a title and an edition, send it to the library, and readers borrow ready copies.
Words you will meet
- Package
- A named folder of Python code people can install
- PyPI
- The public online catalogue of Python packages
- Dependency
- Another package yours needs to work
- Wheel
- A ready-to-install file ending in
.whl - sdist
- The plain source archive of your package
- Metadata
- Facts about the package, like name, version and needs
- API token
- A long secret key used instead of a password to upload
The steps
- 1. Start from zero (12 cards): What a package is, why people publish one, and the plain words behind pip and PyPI.
- 2. Core basics (15 cards): PyPI, pyproject.toml, layout, names, wheels and sdists, and a safe first upload.
- 3. Next steps (15 cards): Dependencies, extras and groups, commands, README and license metadata, versions, data files and testing the real wheel.
- 4. Go deeper (15 cards): Trusted publishing, attestations, safe release pipelines, binary wheels, platform tags and supply chain defence.
All 12 cards in Start from zero
- What does publishing a Python package mean, in one plain sentence?
- It means putting your Python code on a public shelf, called PyPI, so anyone can install it with one short command.
- What problem does a package solve?
- Without one, people copy code files by email or chat. Copies drift apart, fixes never reach everyone, and nobody knows which version they have.
- Where do you already meet published packages?
- Every time someone types
pip installand a tool appears, that tool was published. Data, web and AI projects in Python are built mostly from published packages. - What everyday thing is publishing a package like?
- Publishing a book: you give it a title and edition, send it to a big library catalogue, and readers borrow a ready copy instead of photocopying yours.
- What are a module, a package and
import? - A module is one
.pyfile of Python code; a package is a folder of modules with one name.importloads it into your program so you can use what it offers. - What are
pip, PyPI, an index and a dependency? - PyPI is the main index, a public online catalogue of Python packages, and
pipis the command that downloads and installs from it. A dependency is another package yours needs to work. - What are
pyproject.toml, metadata and a version? pyproject.tomlis a small settings file, written in a format called TOML, that holds your package's metadata: facts like its name, version and needs. A version such as1.4.0means major, minor and fix numbers.- What do build, wheel, sdist and build backend mean?
- Building turns your folder into files ready to upload, saved in
dist/: a wheel (.whl) that installs instantly and an sdist (.tar.gz), the plain source. A build backend is the tool that does the building. - What do upload, API token,
twineand TestPyPI mean? - Uploading sends your built files to PyPI using
twineoruv, with an API token, a long secret key, instead of a password. TestPyPI is a separate practice copy of PyPI for trying it first. - Your first tiny win: what do these three terminal lines do?
- Line 1 makes a virtual environment, a private box of packages for one project. Line 2 turns it on, and line 3 asks pip to install a package from PyPI into it.
- What do you need before you start?
- Python 3.11 or newer, a terminal (the text window for commands), a text editor and a little working Python code to share. A free PyPI account comes in when you upload.
- What will you be able to do after this topic?
- Lay out a package folder, write
pyproject.toml, build a wheel and sdist, test on TestPyPI, upload safely to PyPI with a token, and release fixed versions the right way.
Publish a Python package cheatsheet
Build and upload
rm -rf dist && python -m buildFresh wheel and sdistuv buildSame, fastertwine check --strict dist/*Validate metadata and READMEtwine upload -r testpypi dist/*Rehearse on TestPyPItwine upload dist/*Upload to PyPIuv publishUpload, trusted publishing in CIuv version --bump patchBump the version
pyproject.toml
[build-system] requires / build-backendWhich tool builds itrequires-python = ">=3.11"Supported Pythonsdependencies = ["httpx>=0.27"]Runtime needs, lower bounds[project.optional-dependencies] excel = [...]Opt-in extras[dependency-groups] dev = [...]Dev tools, never published[project.scripts] gst = "gst_tools.cli:main"Install a commandlicense = "MIT"SPDX license expressiondynamic = ["version"]Version from Git tag via plugin
Versions (PEP 440)
1.3.0.dev2Development build, sorts first1.3.0b1Beta pre-release1.3.0rc1Release candidate1.3.0Final release1.3.0.post1Fix to release files, same codepip install --pre pkgAllow pre-releases
Trusted publishing (GitHub)
permissions: id-token: writeOn the publish job onlyenvironment: pypiApproval gate, matches PyPI settinguses: pypa/gh-action-pypi-publish@release/v1Upload with OIDC and attestationswith: repository-url: https://test.pypi.org/legacy/Target TestPyPIuses: actions/download-artifact@v8Fetch dist from the build job
Inspect
unzip -l dist/*.whlFiles inside a wheelpip debug --verboseTags this machine acceptsauditwheel show dist/*.whlLinux wheel compatibilitypip index versions gst-toolsPublished versionspip download pkg --no-deps -d /tmp/xFetch a file to inspect