Skip to content

2. Build

Now that you have written your code, it is time to build a package. This is the first step in making your code available to the world. It is basically the process of going from a directory containing your code to a package that can be installed using a package manager such as pip, conda or uv.

Example

See demo project:

Before | After | Diff

Packaging

To package your code, you need to choose a build system. The most common ones are setuptools and poetry. Each has its own advantages and disadvantages. For a detailed guide, see the official packaging guide.

Project Structure

In short, you want to create a couple of files and restructure your code:

python-package-demo/
├── src/
│   └── python_package_demo/
│       ├── __init__.py
│       └── example.py
├── LICENSE
├── pyproject.toml
├── README.md
└── ...
  • LICENSE: The license file for your project. This is important to let people know how they can use your code.
  • pyproject.toml: The configuration file for your package. This is where you define the build system and other metadata for your package. It can also be used to configurate other tools like ruff, uv, mypy and black.
  • README.md: The readme file for your project. This is where you provide information about your project and how to use it.
  • src/: The source code of your project.

Info

The src/ directory is not required as a parent directory, but it is recommended to use it. It helps to avoid naming conflicts with other packages, and makes it easier to manage your code. For more details, see src layout vs flat layout.

Info

While setup.py is still supported and not deprecated, using a single pyproject.toml to configure your package is the recommended way to go.

pyproject.toml file

As a simple example, we will use setuptools as the build system. The pyproject.toml file is the configuration file for your package. It contains all the metadata and configuration for your package. Here is a simple example:

[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "python-package-demo"
version = "0.1.0"
description = "A demo project for packaging python code"
readme = "README.md"
license = { file = "LICENSE" }
authors = [{name = "Your Name", email = "your-email@mail.org"}]
requires-python = ">=3.8"
dependencies = [
    "numpy>=1.21.0",
    "pandas>=1.3.0",
]

This will already be enough to install your package via pip:

pip install .
# or 
pip install -e . # for editable mode

You can also use pip to build your package:

pip wheel .

This is the way how you publish your package to the world. It is discussed in the publish section.

Info

As you can see, we hardcode the current version into the pyproject.toml file. This means you have to bump the version on each release. setuptools_scm is another build system which can retrieve the version from your git tags. This is how you would manage your releases and trigger a CI pipeline anyway, so you don't have to worry about updating the version in your pyproject.toml file.

More metadata

You can add more metadata to your package. See Writing your pyproject.toml for more information. Here we add some classifiers and keywords to the package. They are picked up by PyPI, for a full list of available classifiers see PyPI Classifiers.

[project]
# ...
classifiers = [
    # Specify the Python versions you support here
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.8",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3 :: Only",
    # License
    "License :: OSI Approved :: MIT License",
    # Operating System
    "Operating System :: OS Independent",
]
keywords = ["python", "package", "demo"]

[project.urls]
Homepage = "https://example.com"

License

The licence file is important to let people know how they can use your code. Tools like choosealicense.com/ can help you choose a licence. There is also an OpenMod Guide for choosing a licence.

Resources