Python Project Setup
Modern Python project setup using uv package manager and pyproject.toml.
Creating a New Project
- •Create project directory and initialize git:
mkdir myproject && cd myproject git init
- •
Copy pyproject.toml and edit:
- •Change
nameto your project name - •Update
description - •Add dependencies to
dependencieslist - •Update
[project.scripts]for CLI entry point
- •Change
- •
Copy gitignore to
.gitignore - •
Copy AGENTS.md to project root (AI agent instructions)
- •
Create package structure:
mkdir myproject touch myproject/__init__.py
- •Initialize uv and install:
uv sync
Project Structure
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
Entry Points
CLI script (installed as command)
[project.scripts] myproject = "myproject.cli:main"
main.py (for python -m)
from myproject.cli import main
if __name__ == "__main__":
main()
Code Quality
Format and lint with ruff:
ruff format . ruff check . --fix
Type Annotations
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.
Structured Data
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
Common Commands
uv sync # Install dependencies uv add requests # Add dependency uv run pytest # Run tests uv build # Build package
GitHub Actions: Publish to PyPI
Setup Steps
- •
Copy publish.yml to
.github/workflows/publish.yml - •
Configure PyPI Trusted Publisher (no API tokens needed):
- •Go to https://pypi.org/manage/account/publishing/
- •Add new pending publisher:
- •PyPI project name:
myproject - •Owner: your GitHub username
- •Repository: your repo name
- •Workflow name:
publish.yml - •Environment:
pypi
- •PyPI project name:
- •
Create GitHub environment:
- •Go to repo Settings → Environments
- •Create environment named
pypi
- •
Release workflow:
- •Create a GitHub release with tag like
v0.1.0 - •Action automatically extracts version from tag and publishes
- •Create a GitHub release with tag like
Publishing a Release
Create 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.