headroom.walls.sh · python

Claude Code for Python

Claude Code handles the parts of Python work that are tedious at scale: writing test suites, adding type annotations, refactoring across many files, fixing mypy errors, and iterating on data analysis scripts. This page covers the patterns that work well for Python projects.

CLAUDE.md for Python projects

Put a CLAUDE.md in your project root to give Claude Code persistent context about the Python environment and conventions:

## Environment
- Python 3.11, virtualenv in .venv/
- Install deps: pip install -e ".[dev]"
- Test: pytest tests/ -v
- Lint: ruff check . && ruff format --check .
- Types: mypy src/ --strict

## Conventions
- All new functions need type annotations
- Use pathlib.Path, not os.path
- Prefer dataclasses for simple value types
- No bare except — use except Exception as e

Claude Code reads this at the start of every session. It will use pytest tests/ -v when running tests and mypy src/ --strict when checking types — without being told each time.

pytest: writing and fixing tests

The test-fix loop works well for Python. Start it with a clear target:

claude "add pytest tests for app/services/auth.py — cover the happy path, invalid token, and expired token cases. Use fixtures, run pytest after."

For parametrized tests across edge cases:

claude "write parametrized pytest tests for the validate_email function — test valid addresses, invalid formats, missing TLD, and unicode domains"

When tests are failing and you want a full fix loop:

claude "run pytest, read the failures, fix the code (not the tests), run again — repeat until green"

Type annotations and mypy

Adding type hints to an existing codebase is repetitive — Claude Code handles it systematically:

claude "add type annotations to all functions in src/api/ that are missing them. Run mypy src/ after to verify."

For fixing a batch of mypy errors:

claude "run mypy src/ --strict, read the errors, fix each one. Don't use Any unless there's no alternative — prefer proper types."

On a large codebase, do it module by module:

claude "add type annotations to src/models/user.py only — run mypy on that file after, fix any errors it introduces"
Type annotations spread across function signatures, return types, and class attributes. Ask Claude Code to do one module at a time — it's easier to review, and mypy errors in one file don't cascade into unrelated failures.

Virtual environments and dependencies

Claude Code can set up a virtualenv, install dependencies, and verify the environment:

claude "set up a virtualenv in .venv/, install the project in editable mode with dev extras, verify pytest runs"

For dependency issues:

claude "pip install is failing with a conflict. Read requirements.txt and pyproject.toml, identify the conflict, and fix it."

If you're migrating from requirements.txt to pyproject.toml:

claude "migrate requirements.txt and requirements-dev.txt to a pyproject.toml with [project] and [project.optional-dependencies] sections. Keep all version pins."

Django workflows

claude "add a new DRF endpoint for user preferences — model, serializer, view, URL registration, and tests. Follow the patterns in the existing users/ app."
claude "write a Django migration for adding a nullable preferences JSONField to the User model. Make it reversible."
claude "the Django test suite is slow. Run it, identify the slowest tests, and look for N+1 queries using select_related/prefetch_related"

Claude Code reads your urls.py, models.py, and existing test files before writing new code — it follows the project's existing patterns rather than inventing new ones.

FastAPI workflows

claude "add a POST /users/{id}/preferences endpoint to the FastAPI app. Include Pydantic models for request/response, add it to the router, write tests with TestClient."
claude "add response_model annotations to all endpoints in app/routers/ that are missing them — infer the types from what the functions return"
claude "the /search endpoint is slow. Profile it with a simple timer, identify whether it's the DB query or the serialization, and fix the bottleneck."

Data science and analysis scripts

For analysis work, Claude Code can iterate on scripts with you:

claude "read data/sales.csv, compute monthly revenue by region, and write a summary to output/summary.csv — use pandas"
claude "the feature engineering in notebooks/prepare.py is slow on large DataFrames. Profile it and optimize the worst functions."
claude "convert this analysis notebook to a clean Python script — remove the cells, keep the logic, add docstrings and type annotations"
Session budget note: data analysis loops — read data, process, check output, adjust, repeat — can accumulate tool calls quickly. Each iteration of "read the output, adjust the script, run again" is 3–6 tool calls. Long exploratory sessions burn through the 5h window faster than most coding tasks.

Refactoring Python codebases

claude "find all functions in src/ that take more than 5 positional arguments and refactor them to use keyword-only arguments or dataclass params"
claude "replace all string concatenation for SQL queries in src/db/ with parameterized queries — look for % formatting and f-strings in execute() calls"
claude "the logging module is used inconsistently — some files use print(), some use logging.info(). Standardize on the logging module across src/"

Keep an eye on your session while Python runs

Headroom — live session usage for Python developers

Test-fix loops, mypy batch fixes, and data analysis iterations all burn Claude Code session budget faster than a simple edit. Headroom shows your 5h session and 7d weekly utilization live in the macOS menu bar — no token, no API key, reads the file Claude Code writes to ~/.claude/.

Install in one line:

brew install patwalls/tap/headroom

Color-coded from calm to amber to red. Know your headroom before you start a long pytest run or a mypy sweep across the whole project.


Writing tests with Claude Code
Refactoring with Claude Code
Debugging with Claude Code
5-hour session limit explained