pip install python-package-repofrom test_packaging import ...# clone the repo
git clone https://github.com/pnimeesha/python-package-prod.git
# install the dev dependencies
make install
# run the tests
make testThese notes summarize key learnings from the course, especially focused on production-ready Python packaging, pre-commit tools, automation, and CI/CD practices.
The pre-commit framework is a way to automatically run checks and linters before committing code to your Git repository. It helps maintain code quality and consistency across teams.
CI Approach 2 β The pre-commit framework
- Configure hooks in
.pre-commit-config.yaml - Install it via
pre-commit install - Hooks like
black,isort,ruff, etc., will auto-format/check your code before each commit
Used for quick experiments, not recommended in production code.
from pathlib import Path
print(Path(__file__)) # Path to current file
print(Path(__file__).parent) # Parent directory of current file
import sys
sys.path.insert(0, "<path-to-your-repo>")setuptools or proper packaging techniques instead.
python3 -m venv .venvThis creates an isolated Python environment to install dependencies without affecting global Python setup.
This is the directory inside your virtual environment (.venv/lib/pythonX.Y/site-packages) where Python packages get installed using pip.
setuptoolssimplifies packaging and distribution.- Every venv includes
pipandsetuptools.
Steps:
- Create
setup.py:
from setuptools import setup, find_packages
setup(
name="your_package",
version="0.0.1",
packages=find_packages(),
install_requires=["numpy"],
)- Build your package:
python setup.py sdist- Install the
.tar.gzpackage locally:
pip install ./dist/your_package-0.0.1.tar.gz- Install in editable mode (great for development):
pip install --editable ./- Easy to generate and distribute
- Assumes system dependencies (like
gcc) - Slower, as it needs to compile on end-user machine
setup.pymay contain arbitrary code β poses a security risk
The .whl format (Python Wheel) is a pre-built binary distribution, making installations faster and safer.
pip install wheel
python setup.py bdist_wheelInclude in setup.py:
setup_requires=["wheel"]Note: This installs
wheeltemporarily, so you can't import it in your code.
Introduced by PEP 518, this replaces the need for setup.py.
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"Then build your project using:
pip install build
python -m build --sdist --wheel .This creates both .tar.gz and .whl files.
Run Ruff using configuration from pyproject.toml:
ruff check --config ./pyproject.toml your_package/You can remove separate config files (.flake8, .pylintrc, etc.) and unify everything under pyproject.toml.
recursive-include your_package/ *.json
[tool.setuptools.package-data]
your_package = ["**/*.json"]If you're using Hatchling instead of Setuptools:
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"Update the respective section accordingly.
pip freeze > requirements.txt
# Visualizing dependency tree
pip install pipdeptree graphviz
pipdeptree -p your_package --graph-output png > dependency-graph.pngIn pyproject.toml:
[project.optional-dependencies]
dev = ["mypy", "ruff", "black"]
colors = ["rich"]
all = ["your_package[dev,colors]"]Install all extras:
pip install '.[all]'In ZSH, quotes around the
.[all]are required.
- Agile vs Waterfall: Agile promotes iterative releases, making tools like PyPI/CD pipelines essential
- PyPI vs TestPyPI: TestPyPI is a sandboxed version of PyPI for testing uploads
-
Generate API tokens:
-
Activate venv and build package:
python -m build --sdist --wheel .- Upload:
pip install twine
twine upload --repository testpypi dist/*- Manage secrets using
.envand shell scripts (run.sh).
Example flow:
./run.sh clean
./run.sh build
./run.sh publish:testβ Always increment version before re-publishing.
sudo apt-get install make- Tab-indented file
- Shell-like syntax
- Efficient, portable, and reproducible
- Similar to
make, but written in Rust - Not as portable as Make
Example:
chmod +x run.sh
./run.sh buildUse echo $@ in scripts to display passed arguments.
- ποΈ Talk Python to Me Podcast
- π Snyk β Python Security Tool