The essentials
Quick reference
One focused task per row. Jump to the related section for complete, working examples.
| Use | Syntax | Examples |
|---|---|---|
| Create a virtual environment | python -m venv .venv | View examples |
| Seed current packaging tools | python -m venv --upgrade-deps .venv | View examples |
| Invoke the environment directly | .venv/bin/python -m pip --version | View examples |
| Declare backend requirements | requires = ['hatchling>=1.26'] # in [build-system] | View examples |
| Select a build backend | build-backend = 'hatchling.build' | View examples |
| Declare Python compatibility | requires-python = '>=3.11' | View examples |
| Declare a runtime dependency | dependencies = ['httpx>=0.27,<1'] | View examples |
| Publish a console command | acme = 'acme.cli:main' # in [project.scripts] | View examples |
| Declare an optional feature | test = ['pytest>=8'] # in [project.optional-dependencies] | View examples |
| Apply deployment constraints | python -m pip install -c constraints.txt -r requirements.txt | View examples |
| Require artifact hashes | python -m pip install --require-hashes -r requirements.txt | View examples |
| Use a src package layout | src/acme/__init__.py | View examples |
| Open packaged text | text = resources.files('acme').joinpath('data.txt').read_text(encoding='utf-8') | View examples |
| Build sdist and wheel | python -m build | View examples |
| Build only a wheel | python -m build --wheel | View examples |
| Install the built wheel | python -m pip install --force-reinstall dist/acme_tools-1.2.0-py3-none-any.whl | View examples |
| Validate distribution metadata | python -m twine check dist/* | View examples |
| Upload to TestPyPI | python -m twine upload --repository testpypi dist/* | View examples |
| Read installed metadata | version = importlib.metadata.version('acme-tools') | View examples |
Modern Python projects declare build requirements and core metadata in pyproject.toml, build isolated source and wheel distributions, and test installation artifacts rather than relying on a source checkout. Virtual environments isolate installed distributions, not operating-system libraries. Reproducibility additionally requires deliberate dependency constraints, hashes where appropriate, and controlled build inputs.
Step by step
Detailed examples
Create and operate an isolated environment
python -m venv creates an environment around a specific interpreter. Activation only adjusts shell variables; invoking the environment's Python directly is more explicit in automation. Environments are disposable and generally not portable because scripts embed absolute interpreter paths. Recreate them from declared inputs instead of copying or committing them.
import sys
inside_venv = sys.prefix != sys.base_prefix
print(type(inside_venv).__name__)
print(sys.base_prefix != "") bool
TrueDeclare the build backend
The [build-system] table tells a frontend which packages to install into an isolated build environment and which backend object to call. Keep requires limited to actual build dependencies and use versions compatible with your supported frontend. A missing table invokes legacy defaults in some tools, so explicit configuration is easier to audit.
import tomllib
document = tomllib.loads("""
[build-system]
requires = ["hatchling>=1.26"]
build-backend = "hatchling.build"
""")
print(document["build-system"]["build-backend"])
print(document["build-system"]["requires"]) hatchling.build
['hatchling>=1.26']Express interoperable project metadata
The [project] table defined by the packaging metadata specification contains name, version or dynamic fields, Python compatibility, dependencies, scripts, classifiers, and URLs. Distribution names and import package names need not match. Declare requires-python honestly so installers reject incompatible interpreters before installation.
import tomllib
project = tomllib.loads("""
[project]
name = "acme-tools"
version = "1.2.0"
requires-python = ">=3.11"
dependencies = ["httpx>=0.27,<1"]
""")["project"]
print(project["name"], project["version"])
print(project["requires-python"])
print(len(project["dependencies"])) acme-tools 1.2.0
>=3.11
1Separate abstract dependencies from locked environments
Project metadata should state compatible dependency ranges, while applications and deployments may use a fully resolved lock or constraints file. Do not copy an environment's complete freeze into a reusable library's runtime dependencies. Evaluate environment markers on every target platform, and treat direct URLs or alternate indexes as supply-chain decisions requiring review.
import sys
minimum = (3, 11)
supported = sys.version_info[:2] >= minimum
print("supported" if supported else "unsupported")
print("target", ".".join(map(str, minimum))) supported
target 3.11Design import and distribution boundaries
A src layout keeps the repository root from silently satisfying imports and helps tests exercise an installed package. Include __init__.py for regular packages unless namespace-package behavior is intentional. Package data needs backend configuration and a runtime access API such as importlib.resources; paths beside the source tree may not exist in an installed wheel.
from importlib import resources
root = resources.files("importlib")
print(root.name)
print(root.is_dir()) importlib
TrueBuild artifacts and test what users install
Use a standards-based frontend to build both an sdist and wheel in isolation. Inspect their contents, install the wheel into a fresh environment, and run tests from outside the repository so local files cannot mask missing package data. An sdist must contain enough source and configuration to reproduce the wheel without network access beyond declared build requirements.
name = "acme-tools".replace("-", "_")
version = "1.2.0"
wheel = f"{name}-{version}-py3-none-any.whl"
print(wheel) acme_tools-1.2.0-py3-none-any.whlPublish immutably and verify provenance
Upload a release once; distribution files on PyPI cannot be replaced under the same filename. Test against TestPyPI or a private staging index, verify metadata and installation, then publish with an API token or trusted publisher rather than a password. Never place credentials in pyproject.toml, command history, or a committed URL.
metadata = {
"name": "acme-tools",
"version": "1.2.0",
"requires_python": ">=3.11",
}
for key in sorted(metadata):
print(f"{key}={metadata[key]}") name=acme-tools
requires_python=>=3.11
version=1.2.0Local code tester
Inspect pyproject metadata
Parse a compact pyproject.toml document with Python's standard-library TOML reader.
Press Run to load Python locally.
Sources and further reading
References
Authoritative documentation used to verify and expand this cheat sheet.
- Python Software Foundationvenv — Creation of virtual environmentsdocs.python.org
- Python Packaging Authoritypyproject.toml specificationpackaging.python.org
- Python Packaging AuthorityDeclaring project metadatapackaging.python.org
- Python Packaging AuthorityPackaging Python Projectspackaging.python.org
- Python Packaging AuthorityThe Packaging Flowpackaging.python.org
- Python Packaging AuthorityRecording installed projectspackaging.python.org
Help us improve
Found a typo or missing example?
Tell us what would make this cheat sheet clearer, more complete, or more useful.



