Python is Claude Code's sweet spot. The combination of Python's readable syntax, rich ecosystem, and the fact that most ML/data engineering work lives in Python means Claude Code tends to perform exceptionally well here — better, in practice, than most developers expect when they first try it.
But getting real value out of it requires more than just typing questions at a terminal. The developers seeing the biggest gains have standardized their Python-specific prompts, set up their CLAUDE.md to give Claude context about their codebase, and built repeatable workflows around the tasks that actually slow them down: debugging, testing, refactoring, and code review.
This guide covers exactly that. No fluff, no "AI is amazing" cheerleading — just patterns that work.
In this guide
1. Setting Up Claude Code for Python Projects
Before writing a single prompt, spend five minutes on setup. This is where most Python developers leave real productivity on the table.
Install and authenticate
npm install -g @anthropic-ai/claude-code
claude # opens in your project directory
Claude Code works best when launched from the root of your Python project, not from a parent directory. It uses the current directory as its context window for file discovery.
Virtual environment awareness
Tip: Tell Claude Code which Python environment you're using upfront. Include your venv path and Python version in your CLAUDE.md (covered below). Claude won't always detect these automatically, and the difference between Python 3.9 and 3.12 matters for type hints and match statements.
What to do on first launch
When you open Claude Code in a new Python project, start with a codebase orientation prompt:
Read the project structure, key dependencies in requirements.txt or pyproject.toml,
and the main entry points. Give me a 3-sentence summary of what this codebase does
and flag anything that looks like tech debt or unusual patterns I should know about.
This primes Claude with context it'll use throughout the session. Skipping this means every follow-up prompt has less context to work with.
2. Your Python CLAUDE.md Template
The CLAUDE.md file is the single most impactful thing you can do to improve Claude Code's output quality for your project. It's a markdown file at your project root that Claude reads automatically at session start — think of it as onboarding documentation written for an AI collaborator.
Here's a battle-tested template for Python projects:
# CLAUDE.md — [Project Name]
## Project Overview
[2-3 sentences: what this is, who uses it, what it does]
## Stack
- Python 3.12 (venv at ./venv)
- [Framework: Django 5.x / FastAPI 0.115 / Flask 3.x]
- Database: [PostgreSQL via psycopg3 / SQLite / etc.]
- Testing: pytest + pytest-cov
- Linting: ruff + mypy (strict)
- Package manager: pip / uv / poetry
## Code Style Rules
- Type hints on all function signatures — no exceptions
- Docstrings: Google style for public functions
- Max line length: 100 chars (ruff configured)
- Use pathlib.Path, not os.path
- Prefer f-strings over .format() or %
- Avoid mutable defaults in function signatures
## Testing Conventions
- Tests live in tests/ mirroring src/ structure
- Use pytest fixtures (conftest.py) for shared state
- Every new function needs a unit test
- Integration tests go in tests/integration/
- Run: pytest tests/ -v --cov=src
## Do Not
- Do not modify requirements.txt without flagging it
- Do not use print() for logging — use logging.getLogger(__name__)
- Do not use bare except: — always catch specific exceptions
- Do not commit secrets — use python-dotenv and .env
## Key Files
- src/main.py — entry point
- src/config.py — all configuration, loaded from env vars
- src/models/ — SQLAlchemy / Pydantic models
- tests/conftest.py — shared fixtures
## Current Focus
[What you're working on this session — update this as you go]
Why this matters: Without CLAUDE.md, Claude Code treats every session like it's meeting your codebase for the first time. With it, you get responses that respect your existing conventions, use your actual testing patterns, and flag genuine deviations from your standards — not generic Python advice.
3. Debugging Workflows That Actually Work
Debugging is where Python developers see the most immediate time savings with Claude Code. But the difference between a useful debug session and a frustrating one comes down to how much context you provide upfront.
The paste-and-explain approach (don't do this)
Most developers start here: paste a stack trace and ask "why is this failing?" Claude will give you an answer, but it's often surface-level because it lacks context about your data flow, environment, and what you've already tried.
The structured debug prompt (do this instead)
I'm debugging a [type of error] in [module/function].
Context:
- What I expected: [specific behavior]
- What's actually happening: [specific behavior]
- Error/traceback: [paste it]
- Relevant code: [paste the function + any called functions]
- What I've already tried: [list attempts]
- Data coming in: [example input values]
Give me your top 3 hypotheses in order of likelihood, then we'll investigate the most likely one.
The "top 3 hypotheses" framing is key. It prevents Claude from latching onto the first plausible explanation and forces a more systematic diagnosis.
Using Claude Code's file reading for deep debugs
For bugs that span multiple files, let Claude read the files directly rather than pasting:
Read src/services/payment_processor.py, src/models/transaction.py,
and tests/test_payment.py. I'm getting a TransactionError on line 47
of payment_processor.py when processing refunds over $500.
Walk me through the execution path and identify where the validation logic breaks.
Tip: Claude Code can read your entire file tree. For complex bugs, let it navigate the code rather than you doing the copying. It'll trace function calls across files in a way that's exhausting to do manually.
Async/await debugging
Python async code is notoriously difficult to debug. A prompt pattern that works well:
I have an asyncio task that's silently failing — no exception raised,
just no output. Here's the task: [paste code]
Check for:
1. Missing await keywords
2. Coroutines that were created but never awaited
3. Exception swallowing in try/except blocks
4. Event loop lifecycle issues
Show me specifically where each issue is in my code, not general async advice.
4. Test Generation and TDD with Claude Code
Test generation is probably Claude Code's most consistently high-value capability for Python developers. The workflow that works best isn't "generate tests for this file" — it's a more targeted approach.
Generate tests for a specific function
Write pytest tests for this function: [paste function]
Requirements:
- Cover: happy path, edge cases, boundary values, error conditions
- Use fixtures for [any shared setup]
- Mock [external dependency] using pytest-mock
- Include a docstring on each test explaining what it validates
- Follow our existing test style from tests/test_users.py
The "follow our existing test style from [file]" instruction is crucial. Without it, you get tests that look foreign to your codebase. With it, Claude matches your naming conventions, assertion style, and fixture patterns.
TDD flow: write the test first
I need to implement a function that [describe behavior in plain English].
Step 1: Write the pytest tests for this function before any implementation.
Cover: [list specific behaviors you need]
Return: [expected return type/values]
Raise: [exceptions on invalid input]
I'll review the tests, then we'll implement the function to pass them.
This is a genuine TDD workflow. It forces you to nail down the spec before writing code, which catches ambiguity early — and Claude Code is good at this because it can hold the spec in mind while generating the implementation.
Improving existing tests
Read tests/test_api.py. Our test coverage is low and tests are mostly happy-path.
Identify:
1. Which functions have weak test coverage
2. What edge cases are missing
3. Any tests that aren't actually testing what they claim to test
Then write 5 new tests that would most improve our confidence in this module.
5. Refactoring Legacy Python
Legacy Python codebases — Python 2 remnants, missing type hints, tangled module dependencies — are where Claude Code shines. But you need to be specific about what "refactor" means.
Adding type hints to an existing codebase
Read src/utils/data_transform.py. Add type hints to all functions following these rules:
- Use Python 3.10+ union syntax (X | Y, not Union[X, Y])
- Import from typing only for complex generics
- Use TypedDict for dict-heavy return types
- Preserve all existing logic exactly — only add type annotations
- Flag any function where the return type is ambiguous and ask me to clarify
Important: Always tell Claude to "preserve all existing logic exactly" when adding type hints or doing formatting-only refactors. Without this constraint, it will sometimes "helpfully" restructure code it thinks is awkward — which introduces bugs and breaks your diff review.
Breaking up a monolithic function
This function is 200 lines and does too many things: [paste function]
Refactor it into smaller, single-responsibility functions. Rules:
- Each function should have one clear job stated in its name
- Keep functions in the same file unless extraction makes sense
- Preserve the existing external interface exactly — callers shouldn't change
- Write tests for each extracted function before showing me the refactored code
Show me the refactored code and a brief explanation of each extraction decision.
Python 2 → 3 migration assistance
Modernize this Python 2 code to Python 3.12: [paste code]
Specifically handle:
- print statements → print()
- unicode/str → str (Python 3 is unicode by default)
- xrange → range
- dict.iteritems() → dict.items()
- except Exception, e → except Exception as e
- Division behavior (// for integer division)
Flag anything that might change behavior, not just syntax.
6. Framework-Specific Tips
Django
Django's conventions (models, views, URL routing, ORM) are well within Claude Code's training data. The key is being explicit about your Django version and patterns:
Django 5.1, PostgreSQL. Write a class-based view for [endpoint description].
- Use Django REST Framework serializers, not raw JSON
- Apply our existing permission classes from apps/core/permissions.py
- Add select_related/prefetch_related to avoid N+1 queries on the queryset
- Include a migration if the model needs changes
I have a slow Django ORM query that's causing timeouts on our list endpoint.
Here's the queryset: [paste queryset]
Here's the model: [paste model]
Table row count: ~2M rows
Optimize this query. Show me the optimized queryset, what indexes to add,
and explain why each change helps.
FastAPI
Write a FastAPI endpoint for [description].
- Use Pydantic v2 models with field validators
- Include proper HTTP status codes and error responses
- Add dependency injection for [db session / auth]
- Generate the OpenAPI examples in the schema
- Follow our existing router pattern from routers/users.py
Review this FastAPI endpoint for security issues: [paste code]
Check specifically for: SQL injection via raw queries, missing auth dependencies,
improper error messages that leak internal info, missing rate limiting,
and any Pydantic models that accept arbitrary extra fields.
Flask
Refactor this Flask route to use application factory pattern and blueprints.
Current code: [paste code]
Target structure: blueprints per domain (auth, api, admin)
Preserve: all existing route paths and response formats
7. 15 High-Value Prompts for Python Developers
Copy, adapt, and use these. They're specific enough to produce useful output, and I've written them for the kinds of tasks Python devs actually do every day.
- Dependency audit: "Read requirements.txt. Flag any packages that are: outdated by more than 2 major versions, have known CVEs, or have better modern alternatives. List them in priority order."
- Docstring generation: "Add Google-style docstrings to all public functions in [file] that are missing them. Include Args, Returns, Raises, and a one-line summary. Don't modify any code."
- Code review: "Review [file] as a senior Python engineer. Flag: anti-patterns, performance issues, security concerns, missing error handling, and anything a junior dev might misunderstand. Be specific — line numbers where relevant."
- Error handling audit: "Find every bare except: and generic except Exception in [module]. For each one, determine what specific exceptions could be raised and rewrite with proper handling."
- Performance profiling guide: "This function is slow: [paste code]. Without running it, identify the most likely performance bottlenecks based on the code patterns. What would you instrument first with cProfile?"
- Data class conversion: "Convert this dict-heavy code to use dataclasses or Pydantic models where appropriate: [paste code]. Preserve all existing behavior."
- Environment variable cleanup: "Audit this codebase for hardcoded values that should be environment variables (credentials, URLs, feature flags, timeouts). List them with suggested variable names."
- Async conversion: "Convert this synchronous function to async/await: [paste function]. Use aiohttp instead of requests. Preserve the external interface so callers don't need to change — except for the await."
- SQL query review: "Review these SQLAlchemy queries for N+1 problems: [paste queries/views]. Show me which ones are problematic and how to fix with select_related equivalent."
- Context manager creation: "I need a context manager for [resource/operation]. Write it using both __enter__/__exit__ and contextlib.contextmanager. Explain the tradeoffs."
- Generator refactor: "This function loads everything into memory: [paste code]. Rewrite it as a generator that processes [items] lazily. Show memory usage before/after in comments."
- CLI with Click: "Build a Click CLI for [tool description]. Include: --verbose flag, --config option that reads from YAML, --dry-run mode, and proper help text. Follow 12-factor app principles."
- Logging setup: "Audit our logging setup: [paste config + usage]. We're missing [context info]. Add structured logging with correlation IDs without breaking existing log format."
- Makefile/task runner: "Write a Makefile with targets for: install, test, lint, format, type-check, run, docker-build, and deploy. Include a help target that documents each command."
- README generation: "Read the project structure, pyproject.toml, and main entry points. Write a developer README with: project overview, setup steps, how to run tests, how to contribute, and environment variable reference."
🐍 Get the Full Python Prompt Library
The CLAUDE.md Team Starter Kit includes 50+ production-ready prompts organized by task type — debugging, testing, refactoring, code review, and more. Plus CLAUDE.md templates for Python, TypeScript, Go, and 6 other stacks.
Get the Starter Kit — $19Instant download · PDF + Markdown · One-time price, no subscription
8. Common Mistakes Python Developers Make With Claude Code
After watching a lot of developers onboard to Claude Code, these are the patterns that consistently produce frustration:
Mistake 1: Trusting output without running it
Claude Code produces plausible-looking Python that can contain subtle bugs — off-by-one errors in loops, incorrect exception hierarchies, wrong async patterns. Run every generated function before committing it. This seems obvious, but the speed of generation creates overconfidence.
Mistake 2: Not specifying your Python version
Python 3.10+ has match statements, X | Y union syntax, and other features that don't exist in 3.8. Without specifying your version in CLAUDE.md, you'll get code that might not run in your environment.
Mistake 3: Pasting too much context at once
More context is usually better, but dumping 1,000 lines into a single prompt produces unfocused responses. For large codebases, let Claude read files directly and navigate with targeted questions rather than manual copy-paste marathons.
Mistake 4: Vague refactor requests
"Clean up this code" is a recipe for Claude making changes you didn't want. Specify exactly what you want: "Add type hints only, don't restructure" or "Extract helper functions, preserve the external API."
Mistake 5: Not using CLAUDE.md at all
This is the big one. Without a CLAUDE.md file, every session starts cold. Claude doesn't know your coding standards, your stack, or your constraints. Setting one up takes 20 minutes and pays for itself on the first debugging session.
The payoff: Python developers who set up CLAUDE.md properly and use structured prompts routinely report cutting debugging time by 40-60% and test coverage going from "aspirational" to actually high — because generating tests is no longer the tedious manual work it used to be.
What Teams Are Doing Differently
The developers seeing the most impact from Claude Code aren't using it as a glorified autocomplete. They've integrated it into their workflow at specific friction points: first pass at debugging, generating test scaffolding, reviewing PRs for patterns, and tackling the legacy refactors that were too expensive to prioritize before.
The common thread is specificity. Generic prompts produce generic output. Prompts that include your stack, your conventions, your current context, and your specific constraints produce output you can actually ship.
If you're going to invest time in getting this right, start with your CLAUDE.md file. It's the one artifact that compounds — every future session gets better because of the work you put in once.
Get the Claude Code Team Playbook
The full playbook includes CLAUDE.md templates for 8 stack types, 100+ prompts organized by workflow stage, team adoption patterns, and a 30-day rollout guide. Used by engineering teams at 50+ companies.
Get the Playbook — $49 →