Module 10 ยท Lesson 34

Packaging and Distribution

๐Ÿ Pythonโฑ 12 min read๐Ÿ“– Professional

Packaging Python Projects

Packaging lets you distribute your code to others via PyPI or as a wheel file. Modern Python packaging uses pyproject.toml and build backends.

# Project structure for a distributable package my-library/ โ”œโ”€โ”€ src/ โ”‚ โ””โ”€โ”€ mylibrary/ โ”‚ โ”œโ”€โ”€ __init__.py โ”‚ โ”œโ”€โ”€ core.py โ”‚ โ””โ”€โ”€ utils.py โ”œโ”€โ”€ tests/ โ”‚ โ””โ”€โ”€ test_core.py โ”œโ”€โ”€ README.md โ”œโ”€โ”€ LICENSE โ””โ”€โ”€ pyproject.toml

pyproject.toml

# pyproject.toml โ€” the modern packaging config [build-system] requires = ["setuptools>=61.0", "wheel"] build-backend = "setuptools.backends.legacy:build" [project] name = "my-awesome-library" version = "1.0.0" description = "A library that does awesome things" readme = "README.md" license = {text = "MIT"} requires-python = ">=3.9" authors = [ {name = "Your Name", email = "you@example.com"} ] keywords = ["python", "utilities", "awesome"] classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", ] dependencies = [ "requests>=2.28.0", ] [project.optional-dependencies] dev = ["pytest", "mypy", "black", "ruff"] [project.urls] Homepage = "https://github.com/you/my-awesome-library" Documentation = "https://docs.my-awesome-library.com" [project.scripts] my-tool = "mylibrary.cli:main" # Command-line entry point

Building and Publishing

# Install build tools pip install build twine # Build distribution packages python -m build # Creates: # dist/my_awesome_library-1.0.0-py3-none-any.whl (wheel) # dist/my_awesome_library-1.0.0.tar.gz (source) # Test on TestPyPI first (safe!) twine upload --repository testpypi dist/* pip install --index-url https://test.pypi.org/simple/ my-awesome-library # Publish to PyPI (for real) twine upload dist/* # After publishing, anyone can install with: # pip install my-awesome-library

Code Quality Tools

# The modern Python code quality stack: # black โ€” auto-formatter (opinionated, no configuration) pip install black black my_module.py # Format file black . # Format entire project black --check . # Check without modifying # ruff โ€” fast linter (replaces flake8, isort, and more) pip install ruff ruff check . # Check for issues ruff check --fix . # Auto-fix what can be fixed ruff format . # Format (ruff can also format) # mypy โ€” static type checker pip install mypy mypy my_module.py # Type check mypy --strict . # Strict mode # pre-commit โ€” run checks before git commit pip install pre-commit # .pre-commit-config.yaml: # repos: # - repo: https://github.com/psf/black # - repo: https://github.com/charliermarsh/ruff-pre-commit # Configure in pyproject.toml # [tool.black] # line-length = 88 # target-version = ["py39", "py310", "py311"] # # [tool.ruff] # select = ["E", "F", "I"] # line-length = 88 # # [tool.mypy] # strict = true

Semantic Versioning

Use SemVer: MAJOR.MINOR.PATCH. Increment MAJOR for breaking changes, MINOR for new features (backward compatible), PATCH for bug fixes.

# 1.0.0 โ€” Initial stable release # 1.0.1 โ€” Bug fix (no API changes) # 1.1.0 โ€” New feature added (backward compatible) # 2.0.0 โ€” Breaking API change # Keep CHANGELOG.md # ## [2.0.0] - 2024-01-15 # ### Breaking Changes # - `old_function()` removed, use `new_function()` instead # # ## [1.1.0] - 2024-01-01 # ### Added # - New `search()` function

Key Takeaways

Practice Exercises

  1. Take a utility module you've written during this course and package it: write pyproject.toml, README.md, and build it. Don't publish yet, just build locally.
  2. Set up black and ruff on your project. Run them and fix any issues they find.
  3. Write a CHANGELOG.md for a hypothetical project showing 3 versions with changes.
  4. Create a command-line entry point in pyproject.toml and test that the command works after installing in a venv.

๐ŸŽ‰ Course Complete!

You've completed Python Mastery โ€” all 34 lessons across 10 modules. You've gone from print("Hello, World!") to generators, async/await, type hints, testing, and packaging.

What's Next?

  • Build something real: pick a project and apply everything you've learned
  • Contribute to open source: find a Python project on GitHub and fix a bug
  • Go deeper: SQLAlchemy, FastAPI, Django, NumPy, machine learning
  • Read Python source: CPython's source is educational; so are big libraries
  • PEP 8: Python's style guide โ€” know it and follow it
โ† Testing with pytest