Python > Deployment and Distribution > Packaging Python Projects > Building Distributions (sdist, wheel)

Building sdist and wheel distributions

This snippet demonstrates how to build source (sdist) and wheel distributions for a Python project using the setuptools library and the build module.

Distributions are essential for sharing and deploying Python packages. A source distribution (sdist) contains the source code and metadata required to build the package, while a wheel distribution is a pre-built, ready-to-install package format.

Project Setup (pyproject.toml)

The pyproject.toml file defines the build system requirements for your project. It specifies the packages needed to build the distribution (in this case, setuptools and wheel) and the build backend.

Having a pyproject.toml is best practice as of 2024 for Python packaging.

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

Project Structure (example)

Example project structure:

my_package/
    my_module.py
    __init__.py
setup.py
pyproject.toml

my_package is your package directory. my_module.py contains your code. setup.py contains instructions on how to package your code.

setup.py file

The setup.py file contains metadata about your package and instructions on how to build and install it.

  • name: The name of your package.
  • version: The version number of your package.
  • packages: A list of packages to include in the distribution (usually found using find_packages()).
  • install_requires: A list of dependencies that must be installed when your package is installed.
  • entry_points: Defines command-line scripts that will be created when your package is installed.
  • author/author_email: Contact information for the developer.
  • description/long_description: A short description, as well as a longer description, often from a README file.
  • classifiers: Metadata used by the Python Package Index to categorize your package.

from setuptools import setup, find_packages

setup(
    name='my_package',
    version='0.1.0',
    packages=find_packages(),
    install_requires=[],
    entry_points={
        'console_scripts': [
            'my_package=my_package.my_module:main',
        ],
    },
    author='Your Name',
    author_email='your.email@example.com',
    description='A short description of your package',
    long_description=open('README.md').read(),
    long_description_content_type='text/markdown',
    url='https://github.com/yourusername/my_package',
    classifiers=[
        'Programming Language :: Python :: 3',
        'License :: OSI Approved :: MIT License',
        'Operating System :: OS Independent',
    ],
)

Building Distributions (using build)

This code snippet uses the build module to create both sdist and wheel distributions. It executes the python -m build --sdist --wheel dist command. The check=True argument ensures that an exception is raised if the build process fails.

The resulting distributions are placed in the dist directory (or the output_dir you specify).

import subprocess

def build_distributions(output_dir='dist'):
    try:
        subprocess.run(['python', '-m', 'build', '--sdist', '--wheel', output_dir], check=True)
        print(f'Successfully built sdist and wheel distributions in {output_dir}')
    except subprocess.CalledProcessError as e:
        print(f'Error building distributions: {e}')

if __name__ == '__main__':
    build_distributions()

Running the script

Save the above script (along with the pyproject.toml and setup.py) as e.g., build_script.py, then run it from your project's root directory using:

python build_script.py

This command will generate the sdist and wheel files in the dist directory.

Concepts Behind the Snippet

This snippet leverages the standard Python packaging tools, setuptools and build, to create distribution packages. setuptools defines the build process and metadata, while build simplifies the process of invoking the build backend.

Understanding the pyproject.toml and setup.py files is crucial for customizing the build process. The build command simplifies building both sdist and wheel distributions in one go.

Real-Life Use Case

Imagine you've developed a utility library that you want to share with your team or publish to PyPI. Building distributions allows you to package your code and make it easily installable using pip. Without distributions, users would have to manually copy your code and install dependencies, which is error-prone and inconvenient.

Best Practices

  • Use a pyproject.toml file to specify build dependencies and backend.
  • Keep your setup.py file clean and well-documented.
  • Include a README.md file with a detailed description of your package.
  • Use a version control system (like Git) to manage your code.
  • Test your package thoroughly before releasing it.

Interview Tip

Be prepared to explain the difference between sdist and wheel distributions, and the purpose of the pyproject.toml and setup.py files. You should also be able to discuss the advantages of using a build tool like build.

When to use them

Use sdist and wheel distributions whenever you want to share your Python code with others, whether it's within your team, on PyPI, or through other distribution channels. Distributions ensure that your code is packaged correctly and can be easily installed with dependencies.

Alternatives

While setuptools and build are the most common tools for building Python distributions, other options exist, such as:

  • poetry: A dependency management and packaging tool that simplifies the process of creating and publishing Python packages.
  • flit: A simple packaging tool that focuses on ease of use.
  • pdm: A modern Python package and dependency manager supporting PEP 621.

Pros

  • Standardized packaging format.
  • Easy installation with pip.
  • Dependency management.
  • Wide support across the Python ecosystem.

Cons

  • Can be complex to configure for advanced use cases.
  • Requires a setup.py file or pyproject.toml configuration.

FAQ

  • What is the difference between sdist and wheel?

    sdist (source distribution) contains the source code and metadata, while wheel is a pre-built, ready-to-install package format. Wheel installations are faster as they don't require compilation.
  • What is pyproject.toml?

    pyproject.toml is a configuration file that specifies build requirements and backend for your Python project. It's the recommended way to define your project's build system.
  • How do I upload my package to PyPI?

    First, register an account on PyPI. Then, use twine to upload your distributions: twine upload dist/*. You'll need to enter your PyPI credentials.