Set up a modern Python project with uv, pyproject.toml, and ruff. Use when creating a new Python project, package, or CLI tool.
Modern Python project setup using uv package manager and pyproject.toml.
mkdir myproject && cd myproject
git init
Copy pyproject.toml and edit:
name to your project namedescriptiondependencies list[project.scripts] for CLI entry pointCopy gitignore to
.gitignoreCopy AGENTS.md to project root (AI agent instructions)
Create package structure:
mkdir myproject
touch myproject/__init__.py
uv sync
myproject/
├── myproject/
│ ├── __init__.py
│ ├── __main__.py # For `python -m myproject`
│ └── cli.py # CLI entry point
├── pyproject.toml
├── .gitignore
├── AGENTS.md # AI agent instructions
└── uv.lock # Generated by uv
[project.scripts]
myproject = "myproject.cli:main"
from myproject.cli import main
if __name__ == "__main__":
main()
Format and lint with ruff:
ruff format .
ruff check . --fix
Required for all new code:
def greet(name: str) -> None:
print(f"Hello, {name}")
def add(a: int, b: int) -> int:
return a + b
Use Python 3.11+ built-in generics: list[str], dict[str, int], not List, Dict.
Use TypedDict for dictionary shapes (e.g., JSON, API responses):
from typing import TypedDict
class Ticket(TypedDict):
key: str
summary: str
status: str
assignee: str | None
Use dataclass for objects with behavior or defaults:
from dataclasses import dataclass
@dataclass
class Config:
site: str
email: str
timeout: int = 30
uv sync # Install dependencies
uv add requests # Add dependency
uv run pytest # Run tests
uv build # Build package
Copy publish.yml to .github/workflows/publish.yml
Configure PyPI Trusted Publisher (no API tokens needed):
myprojectpublish.ymlpypiCreate GitHub environment:
pypiRelease workflow:
v0.1.0Create a GitHub release using gh release create:
gh release create v0.1.0 --title "v0.1.0" --notes "Release notes here"
Or use --generate-notes to auto-generate from commits:
gh release create v0.1.0 --generate-notes
GitHub Actions will automatically update the version in pyproject.toml and publish to PyPI.
Do NOT manually edit the version in pyproject.toml - it is managed by GitHub Actions.