Help us improve
Share bugs, ideas, or general feedback.
From python-master
Sets up modern Python projects with uv package manager for fast dependencies, pyproject.toml config, virtual environments, ruff linting/formatting, src layout, and PyPI publishing.
npx claudepluginhub josiahsiegel/claude-plugin-marketplace --plugin python-masterHow this skill is triggered — by the user, by Claude, or both
Slash command
/python-master:python-package-managementThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
| uv Command | Purpose |
Replaces pip, pip-tools, pipx, pyenv, virtualenv, and poetry for Python package and project management. Covers uv add, uv sync, uv run, uv init, build, publish, and workspace commands.
Manages Python projects with uv: initializes projects, adds/removes dependencies, handles lockfiles and syncing, configures pyproject.toml. Use for uv init, add, remove, lock, sync.
Manages Python dependencies, virtual environments, and project setup using the uv package manager. Use for faster pip workflows, lockfiles, and modern Python project scaffolding.
Share bugs, ideas, or general feedback.
| 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 |
Use for project setup and dependencies:
Related skills:
python-github-actionspython-testingpython-type-hintsModern 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.
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
irm https://astral.sh/uv/install.ps1 | iex
# pip (works everywhere)
pip install uv
# Homebrew
brew install uv
# Create new project
uv init my-project
cd my-project
# Add dependencies
uv add requests fastapi pydantic
# Add dev dependencies
uv add --dev pytest ruff mypy
# Sync environment (install all dependencies)
uv sync
# Run commands in the environment
uv run python main.py
uv run pytest
# Package management
uv add <package> # Add dependency
uv add <package>==1.0.0 # Specific version
uv add --dev <package> # Dev dependency
uv remove <package> # Remove dependency
uv sync # Sync environment with lockfile
# Virtual environments
uv venv # Create .venv
uv venv --python 3.12 # Specific Python version
uv venv my-env # Named environment
# pip compatibility
uv pip install <package> # Install (faster pip)
uv pip install -r requirements.txt
uv pip freeze > requirements.txt
uv pip compile pyproject.toml -o requirements.txt
# Python management
uv python install 3.13 # Install Python version
uv python list # List installed versions
uv python pin 3.12 # Pin project Python version
# Running
uv run <command> # Run in virtual env
uv run --with httpx python # Run with temporary package
[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",
]
# Lockfile is auto-generated and should be committed
# Contains exact versions for reproducibility
# Update all dependencies
uv lock --upgrade
# Update specific package
uv lock --upgrade-package requests
# Install from lockfile only
uv sync --frozen
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
my-project/
├── my_package/
│ ├── __init__.py
│ └── main.py
├── tests/
│ └── test_main.py
├── pyproject.toml
└── README.md
[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"]
# Ruff configuration
[tool.ruff]
target-version = "py311"
line-length = 88
src = ["src", "tests"]
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # Pyflakes
"I", # isort
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
"ARG", # flake8-unused-arguments
"SIM", # flake8-simplify
]
ignore = [
"E501", # line too long (handled by formatter)
]
[tool.ruff.lint.isort]
known-first-party = ["my_package"]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
# Mypy configuration
[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
# Pytest configuration
[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",
]
# Coverage configuration
[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:",
]
# Linting
ruff check . # Check for issues
ruff check --fix . # Auto-fix issues
ruff check --watch . # Watch mode
# Formatting
ruff format . # Format all files
ruff format --check . # Check formatting
# Both
ruff check --fix . && ruff format .
# pyproject.toml
[tool.ruff]
target-version = "py311"
line-length = 88
src = ["src", "tests"]
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # Pyflakes
"I", # isort
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
"ARG", # flake8-unused-arguments
"SIM", # flake8-simplify
"TCH", # flake8-type-checking
"PTH", # flake8-use-pathlib
"ERA", # eradicate (commented code)
"PL", # Pylint
"PERF", # Perflint
"RUF", # Ruff-specific rules
]
ignore = [
"E501", # line too long (handled by formatter)
"PLR0913", # too many arguments
]
# Per-file ignores
[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["S101"] # Allow assert in tests
"__init__.py" = ["F401"] # Allow unused imports
[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-config.yaml
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
# 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
# From uv
uv pip compile pyproject.toml -o requirements.txt
uv pip compile pyproject.toml --extra dev -o requirements-dev.txt
# From pip-tools
pip-compile pyproject.toml -o requirements.txt
pip-compile pyproject.toml --extra dev -o requirements-dev.txt
# Freeze current environment (not recommended for reproducibility)
pip freeze > requirements.txt
# Recommended: Project-local .venv
project/
├── .venv/ # Virtual environment here
├── src/
├── tests/
└── pyproject.toml
# uv creates .venv by default
uv venv
# Explicit location
uv venv .venv
python -m venv .venv
# 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/
# Usually not needed with uv - just use `uv run`
# Linux/macOS
source .venv/bin/activate
# Windows (PowerShell)
.venv\Scripts\Activate.ps1
# Windows (cmd)
.venv\Scripts\activate.bat
# Deactivate
deactivate
# Build with uv
uv build
# Publish to PyPI
uv publish
# Or with twine
pip install twine
twine upload dist/*
# Test PyPI first
twine upload --repository testpypi dist/*
# pyproject.toml - dynamic version from __init__.py
[project]
dynamic = ["version"]
[tool.hatch.version]
path = "src/my_package/__init__.py"
# src/my_package/__init__.py
__version__ = "1.0.0"