| name | python-package-management |
| description | Complete Python package management system. PROACTIVELY activate for: (1) uv package manager (10-100x faster), (2) pyproject.toml configuration, (3) Virtual environment setup, (4) Dependency management with uv.lock, (5) Ruff linting and formatting, (6) src layout project structure, (7) Publishing to PyPI, (8) pip and requirements.txt. Provides: uv commands, pyproject.toml templates, ruff config, pre-commit setup. Ensures modern Python project setup with fast tooling.
|
| auto_load | {"enabled":true,"triggers":{"keywords":["uv","pip","package","dependency","pyproject","venv","virtual","install"],"file_patterns":["pyproject.toml","requirements*.txt","setup.py"]},"priority":"high","load_with":["python-fundamentals"]} |
Quick Reference
| uv Command | Purpose |
|---|
uv init my-project | Create new project |
uv add <package> | Add dependency |
uv add --dev <package> | Add dev dependency |
uv sync | Install all dependencies |
uv run <command> | Run in virtual env |
uv lock --upgrade | Update all deps |
uv python install 3.13 | Install Python version |
| Tool | Command | Speed |
|---|
| uv | uv add requests | 10-100x faster |
| pip | pip install requests | Baseline |
| ruff Command | Purpose |
|---|
ruff check . | Lint code |
ruff check --fix . | Auto-fix issues |
ruff format . | Format code |
| Project Layout | Recommended |
|---|
| src layout | src/my_package/ |
| Tests | tests/ |
| Config | pyproject.toml |
When to Use This Skill
Use for project setup and dependencies:
- Starting new Python projects
- Setting up uv for fast package management
- Configuring pyproject.toml
- Setting up linting with ruff
- Publishing packages to PyPI
Related skills:
- For CI/CD: see
python-github-actions
- For testing: see
python-testing
- For type hints config: see
python-type-hints
Python Package Management (2025)
Overview
Modern Python package management centers around uv (the fast Rust-based tool), pip, and pyproject.toml. This guide covers best practices for dependency management, virtual environments, and project configuration.
uv - The Modern Package Manager
Why uv?
- 10-100x faster than pip (written in Rust)
- Replaces pip, pip-tools, pipx, poetry, pyenv, virtualenv
- Automatic virtual environment management
- Lockfile support for reproducibility
- ~200x faster venv creation
Installation
curl -LsSf https://astral.sh/uv/install.sh | sh
irm https://astral.sh/uv/install.ps1 | iex
pip install uv
brew install uv
Quick Start
uv init my-project
cd my-project
uv add requests fastapi pydantic
uv add --dev pytest ruff mypy
uv sync
uv run python main.py
uv run pytest
Basic Commands
uv add <package>
uv add <package>==1.0.0
uv add --dev <package>
uv remove <package>
uv sync
uv venv
uv venv --python 3.12
uv venv my-env
uv pip install <package>
uv pip install -r requirements.txt
uv pip freeze > requirements.txt
uv pip compile pyproject.toml -o requirements.txt
uv python install 3.13
uv python list
uv python pin 3.12
uv run <command>
uv run --with httpx python
pyproject.toml with uv
[project]
name = "my-project"
version = "0.1.0"
description = "My Python project"
readme = "README.md"
requires-python = ">=3.11"
license = {text = "MIT"}
authors = [
{name = "Your Name", email = "you@example.com"}
]
dependencies = [
"fastapi>=0.100.0",
"pydantic>=2.0.0",
"httpx>=0.25.0",
]
[project.optional-dependencies]
dev = [
"pytest>=8.0.0",
"ruff>=0.1.0",
"mypy>=1.8.0",
]
[project.scripts]
my-cli = "my_project.cli:main"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.uv]
dev-dependencies = [
"pytest>=8.0.0",
"ruff>=0.1.0",
"mypy>=1.8.0",
]
uv.lock
uv lock --upgrade
uv lock --upgrade-package requests
uv sync --frozen
Project Structure
Recommended: src Layout
my-project/
โโโ src/
โ โโโ my_package/
โ โโโ __init__.py
โ โโโ main.py
โ โโโ models.py
โ โโโ utils/
โ โโโ __init__.py
โ โโโ helpers.py
โโโ tests/
โ โโโ __init__.py
โ โโโ conftest.py
โ โโโ test_main.py
โ โโโ test_models.py
โโโ docs/
โ โโโ index.md
โโโ pyproject.toml
โโโ uv.lock
โโโ README.md
โโโ LICENSE
โโโ .gitignore
Why src Layout?
- Prevents import confusion - Can't accidentally import from project root
- Forces installation - Must install package to test
- Cleaner distributions - Only package code in wheels
- Semantic clarity - Clear separation of code, tests, docs
Flat Layout (for simpler projects)
my-project/
โโโ my_package/
โ โโโ __init__.py
โ โโโ main.py
โโโ tests/
โ โโโ test_main.py
โโโ pyproject.toml
โโโ README.md
pyproject.toml Complete Reference
[project]
name = "my-project"
version = "1.0.0"
description = "A comprehensive Python project"
readme = "README.md"
requires-python = ">=3.11"
license = {text = "MIT"}
keywords = ["python", "example", "package"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
authors = [
{name = "Your Name", email = "you@example.com"}
]
maintainers = [
{name = "Maintainer", email = "maintainer@example.com"}
]
dependencies = [
"fastapi>=0.100.0",
"pydantic>=2.0.0",
"sqlalchemy>=2.0.0",
]
[project.optional-dependencies]
dev = [
"pytest>=8.0.0",
"pytest-cov>=4.0.0",
"ruff>=0.1.0",
"mypy>=1.8.0",
"pre-commit>=3.0.0",
]
docs = [
"mkdocs>=1.5.0",
"mkdocs-material>=9.0.0",
]
all = ["my-project[dev,docs]"]
[project.scripts]
my-cli = "my_package.cli:main"
[project.entry-points."my_package.plugins"]
plugin1 = "my_package.plugins:Plugin1"
[project.urls]
Homepage = "https://github.com/user/my-project"
Documentation = "https://my-project.readthedocs.io"
Repository = "https://github.com/user/my-project"
Changelog = "https://github.com/user/my-project/blob/main/CHANGELOG.md"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["src/my_package"]
[tool.ruff]
target-version = "py311"
line-length = 88
src = ["src", "tests"]
[tool.ruff.lint]
select = [
"E",
"W",
"F",
"I",
"B",
"C4",
"UP",
"ARG",
"SIM",
]
ignore = [
"E501",
]
[tool.ruff.lint.isort]
known-first-party = ["my_package"]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
[tool.mypy]
python_version = "3.12"
strict = true
warn_return_any = true
warn_unused_ignores = true
disallow_untyped_defs = true
plugins = ["pydantic.mypy"]
[[tool.mypy.overrides]]
module = "tests.*"
disallow_untyped_defs = false
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_functions = ["test_*"]
addopts = [
"-ra",
"-q",
"--strict-markers",
"--cov=src/my_package",
"--cov-report=term-missing",
]
[tool.coverage.run]
branch = true
source = ["src/my_package"]
omit = ["*/tests/*", "*/__init__.py"]
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"raise NotImplementedError",
"if TYPE_CHECKING:",
]
Ruff - Linting and Formatting
Why Ruff?
- 10-100x faster than Flake8, Black combined
- Single tool for linting AND formatting
- 800+ built-in rules
- Auto-fix capabilities
- Written in Rust (by Astral, same as uv)
Basic Usage
ruff check .
ruff check --fix .
ruff check --watch .
ruff format .
ruff format --check .
ruff check --fix . && ruff format .
Configuration
[tool.ruff]
target-version = "py311"
line-length = 88
src = ["src", "tests"]
[tool.ruff.lint]
select = [
"E",
"W",
"F",
"I",
"B",
"C4",
"UP",
"ARG",
"SIM",
"TCH",
"PTH",
"ERA",
"PL",
"PERF",
"RUF",
]
ignore = [
"E501",
"PLR0913",
]
[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["S101"]
"__init__.py" = ["F401"]
[tool.ruff.lint.isort]
known-first-party = ["my_package"]
force-single-line = true
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"
Pre-commit Integration
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.0
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.9.0
hooks:
- id: mypy
additional_dependencies:
- pydantic
- types-requests
pip and requirements.txt
When to Use pip
- Production environments requiring stability
- Legacy projects
- Simple scripts without complex dependencies
requirements.txt Best Practices
# requirements.txt - Pinned versions for production
fastapi==0.109.0
pydantic==2.5.3
sqlalchemy==2.0.25
httpx==0.26.0
# requirements-dev.txt
-r requirements.txt
pytest==8.0.0
ruff==0.1.14
mypy==1.8.0
Generating requirements.txt
uv pip compile pyproject.toml -o requirements.txt
uv pip compile pyproject.toml --extra dev -o requirements-dev.txt
pip-compile pyproject.toml -o requirements.txt
pip-compile pyproject.toml --extra dev -o requirements-dev.txt
pip freeze > requirements.txt
Virtual Environment Best Practices
Location
project/
โโโ .venv/
โโโ src/
โโโ tests/
โโโ pyproject.toml
uv venv
uv venv .venv
python -m venv .venv
.gitignore
# Virtual environments
.venv/
venv/
ENV/
env/
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
# Distribution
build/
dist/
*.egg-info/
# IDE
.idea/
.vscode/
*.swp
*.swo
# Testing
.pytest_cache/
.coverage
htmlcov/
.mypy_cache/
# Ruff
.ruff_cache/
Activation (when needed)
source .venv/bin/activate
.venv\Scripts\Activate.ps1
.venv\Scripts\activate.bat
deactivate
Publishing Packages
Build and Publish
uv build
uv publish
pip install twine
twine upload dist/*
twine upload --repository testpypi dist/*
Version Management
[project]
dynamic = ["version"]
[tool.hatch.version]
path = "src/my_package/__init__.py"
__version__ = "1.0.0"