From Zero to One: Building and Publishing a Python Package

By Yangming Li

Light Dark

Introduction

Packaging your Python code is the best way to share, reuse, and distribute your work. This guide walks you through every step of building, testing, documenting, and publishing a modern Python package, following best practices and official recommendations.

1. Project Structure & Initialization

Start with a clean directory layout. The recommended structure is:

my_package/
├── src/
│   └── my_package/
│       ├── __init__.py
│       └── core.py
├── tests/
├── pyproject.toml
├── setup.py         # optional but helpful
├── README.md
└── LICENSE

This structure ensures your package is importable, testable, and future-proof.

2. Writing Core Functionality

In core.py, define your main functions:

def add(a, b):
    return a + b

Expose them in __init__.py:

from .core import add
__all__ = ["add"]

This allows users to import directly: from my_package import add

3. Configuration: setup.py vs pyproject.toml

Modern (recommended):

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

[project]
name = "my-package"
version = "0.1.0"
description = "Example Python package"
readme = "README.md"
requires-python = ">=3.7"
dependencies = []

Legacy (setup.py):

from setuptools import setup, find_packages

setup(
    name="my_package",
    version="0.1.0",
    packages=find_packages("src"),
    package_dir={"": "src"},
    install_requires=[],
)

Use pyproject.toml for modern, future-proof packaging.

4. Testing

Add tests in tests/ using pytest or unittest:

def test_add():
    from my_package import add
    assert add(2, 3) == 5

Testing ensures your package works as expected and is essential for CI/CD.

5. Documentation & Licensing

  • README.md: Explain installation, usage, and examples.
  • LICENSE: Choose a license (MIT, Apache, etc.).
  • .gitignore: Ignore build artifacts (dist/, *.egg-info/).

6. Build & Deploy

Install build tools and create a distribution:

pip install wheel build twine
python -m build

Upload to PyPI or TestPyPI:

# Test PyPI
python -m twine upload --repository testpypi dist/*
# Production
python -m twine upload dist/*

Once published, users can install with pip install my-package.

7. Versioning & Automation

  • Use Git and tag-based versioning.
  • Maintain a CHANGELOG.md.
  • Set up CI/CD (e.g., GitHub Actions) for linting, testing, building, and publishing.

A simple GitHub Actions workflow for testing and publishing:

# .github/workflows/python-package.yml
name: Python Package

on:
  push:
    tags:
      - 'v*'

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.x'
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install pytest
        pip install -e .
    - name: Test with pytest
      run: pytest
      
  publish:
    needs: test
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.x'
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install build twine
    - name: Build and publish
      env:
        TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
        TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
      run: |
        python -m build
        twine upload dist/*

8. Recommended Resources

Conclusion

By following these steps and referencing the official guides, you can confidently create, test, document, and release a Python package from scratch. Happy packaging!

References

  1. Python Packaging Authority. (2023). Packaging Python Projects. Python Packaging User Guide. https://packaging.python.org/tutorials/packaging-projects/
  2. Beuzen, T., & Timbers, T. (2022). Python Packages. https://py-pkgs.org/
  3. pyOpenSci. (2023). Python Packaging Guide. https://pyopensci.org/python-package-guide/
  4. Hillard, D. (2022). Publishing Python Packages. Manning Publications.
  5. PyPA. (2023). PEP 518 -- Specifying Minimum Build System Requirements for Python Projects. https://peps.python.org/pep-0518/