On this page
Packaging and Virtual Environments
Virtual Environments
Isolate project dependencies:
python -m venv .venv
source .venv/bin/activate # macOS/Linux
# .venv\Scripts\activate # Windows
pip install requests
pip freeze > requirements.txt
pip install -r requirements.txt
deactivate
pyproject.toml (Modern Standard)
[project]
name = "mytool"
version = "0.1.0"
description = "A useful CLI tool"
requires-python = ">=3.10"
dependencies = [
"requests>=2.28",
"click>=8.0",
]
[project.optional-dependencies]
dev = ["pytest", "black", "mypy"]
[project.scripts]
mytool = "mytool.cli:main"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
Install in editable mode during development:
pip install -e ".[dev]"
Project Structure
mytool/
├── pyproject.toml
├── src/
│ └── mytool/
│ ├── __init__.py
│ └── cli.py
└── tests/
└── test_cli.py
Publishing to PyPI
pip install build twine
python -m build
twine upload dist/*
Register at pypi.org first. Use TestPyPI for practice uploads.
Version Management Tools
| Tool | Purpose |
|---|---|
| venv | Built-in virtual environments |
| pip | Package installer |
| poetry | Dependency management + publishing |
| uv | Fast modern pip/venv alternative |
| pyenv | Manage multiple Python versions |
Best Practices
- Always use a virtual environment per project
- Pin dependencies in
requirements.txtorpyproject.toml - Use
src/layout for packages - Include
README.md,LICENSE, and tests before publishing - Never commit
.venv/to git — add to.gitignore
Proper packaging separates hobby scripts from professional, shareable Python software.
Poetry Alternative
curl -sSL https://install.python-poetry.org | python3 -
poetry new mytool
poetry add requests
poetry add --group dev pytest
poetry run pytest
poetry build
poetry publish
Poetry manages venv, lock file, and publishing in one tool.
.gitignore Essentials
.venv/
__pycache__/
*.pyc
dist/
*.egg-info/
.env
Version Pinning Strategies
# pyproject.toml
dependencies = [
"requests>=2.28,<3.0", # compatible release
"pandas==2.1.0", # exact pin for reproducibility
]
Pin exact versions for applications; use ranges for libraries.
Editable Installs for Development
pip install -e ".[dev]"
Changes in src/ are immediately importable without reinstalling.
Publishing Checklist
- Choose a unique name on PyPI (check pypi.org)
- Write
README.mdwith install and usage examples - Add
LICENSEfile (MIT, Apache 2.0, etc.) - Configure
[project.urls]inpyproject.toml - Test upload to TestPyPI first
- Tag release in Git matching version number