Skip to main content

build a python package

This example repo:

  • uses build, setuptools and pyproject.toml to build package
  • uses setup.py to build package
  • uses twine to upload package to PyPI package index
  • uses pip or setup.py to install package

PyPI package url: https://pypi.org/project/my-pkg-binlecode/

pyenv shell 3.9.7
python -m venv venv
source venv/bin/activate
python -m pip install --upgrade pip build wheel setuptools twine

Ref: python package doc: https://packaging.python.org/en/latest/tutorials/packaging-projects/

Ref: setuptools doc: https://setuptools.pypa.io/en/latest/userguide/index.html

use native build

Build with pyproject.toml, with setuptools as backend.

This build and upload flow is implemented in git action pull-request flow:

rm -rf build dist *.egg-info
python -m build

upload to PyPI

First, register PyPI account if not yet.

Upload to package index PyPI using twine:

# optional: --skip-existing
python -m twine upload --skip-existing dist/*

Uploading distributions to https://upload.pypi.org/legacy/
Enter your username: binlecode
Enter your password:
Uploading my_pkg_binlecode-0.0.3-py3-none-any.whl
100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 9.0/9.0 kB • 00:00 • 3.2 MB/s
Uploading my_pkg_binlecode-0.0.3.tar.gz
100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 9.1/9.1 kB • 00:00 • 5.7 MB/s

View at:
https://pypi.org/project/my-pkg-binlecode/0.0.3/

Alternatively, PyPI supports api token to replace interactive user credentials. First, get API token from pypi.org, then assign it to env var TWINE_USERNAME.

TWINE_USERNAME=token TWINE_PASSWORD=pypi-XXX... python -m twine upload --skip-existing dist/*

Replace env var setting with $HOME/.pypirc:

[pypi]
  username = __token__
  password = pypi-XXX...

use setuptools and setup.py

Use setup.py script to build. Distribution types should be specified.

This is implemented as git action publish workflow.

build sdist

Build source distribution:

python setup.py sdist

This generates source distribution:

  • dist folder that contains <package-name>-<version>.tar.gz
  • .egg-info folder

A source distribution contains source code. That includes not only Python code but also the source code of any extension modules (usually in C or C++) bundled with the package. With source distributions, extension modules are compiled on the user’s side rather than the developer’s.

Source distributions also contain a bundle of metadata sitting in a directory called <package-name>.egg-info. Egg distribution format is being replaced by wheel distribution format.

build bdist_wheel

python setup.py bdist_wheel generates:

  • dist/---.whl

A wheel file is essentially a zip archive with metadata of supported python versions and platforms.

Usually both source and wheel distributions should be generated and uploaded to package index (PyPI) for download and install.

rm -rf build dist *.egg-info
python setup.py sdist bdist_wheel

Upload package to PyPI (First, register PyPI account if not yet.):

python -m twine upload --skip-existing dist/*

install package

pip install <package-name> is a general way of installing package. pip always prefers wheel distribution over source distribution. If wheel distribution is available for the target platform, source distribution will be used to build package at client side.

To install from local, for example, the package project folder, pip install . installs the package from current folder.

Local install is handy for development mode, where -e/--editable flag is enabled to instruct python to track change in target package project folder: pip install --editable ..

pip install on wheel skips setup.py execution, if wheel is not available, pip has to:

  • download the source distribution and extract it
  • run python setup.py install on the extracted folder to build and install

Inside package folder, use --editable flag for development mode: python setup.py install --editable ..

about pyproject.toml

A later PEP517 standard defines pyproject.toml as the new standard for packaging and distributing python modules.

If there's no pyproject.toml available, setuptools will fall back to setup.py file.

pytest

There are two test folders, one is inside package folder, the other is stand-alone at project root.

To invoke pytest on in package tests, run pytest with package name, pytest will resolve test modules and testing functions.

Running pytest with pytest .. instead of python -m pytest .. yields nearly equivalent behaviour, except that the latter will add the current directory to sys.path, which is standard python behavior.

python -m pytest my_pkg
# or
pytest my_pkg

To invoke pytest on the root level tests folder, make sure __init__.py file is in the folder to make it a package:

python -m pytest tests
# or
pytest tests

Metadata

Release files for my-pkg-binlecode 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for my-pkg-binlecode 0.1.3
File Size Uploaded Provenance
my_pkg_binlecode-0.1.3.tar.gz 3.9 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for my-pkg-binlecode 0.1.3
File Interpreter ABI Platform
my_pkg_binlecode-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 7.6 kB

Release files / my_pkg_binlecode-0.1.3.tar.gz

Download URL my_pkg_binlecode-0.1.3.tar.gz
Size 3.9 kB
Tags Source
SHA-256 checksum
How to use checksums
e78cdd5c7b347f896a299ce4aa8b29c2590e6036001b64d4ae81457f2c969b9e
BLAKE2b-256 checksum
How to use checksums
a7578e5ba248e4f187c0addf27f51d51eaffdc36c0ed4d5d9e13b7c5c122923f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.10.7

Release files / my_pkg_binlecode-0.1.3-py3-none-any.whl

Download URL my_pkg_binlecode-0.1.3-py3-none-any.whl
Size 3.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bb798d7f1cf37613e79e203ac640fe86b15afee8e254219c21298fe2c750b0e6
BLAKE2b-256 checksum
How to use checksums
99b554d557a8d66bb6d11024e437dfaa22940307ed83ebe479420445e91eb97c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.10.7

Security for my-pkg-binlecode 0.1.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page