Venvs, pytest, Django, FastAPI, pandas, type hints — everything you need to use Claude Code effectively in your Python projects.
Claude Code inherits the shell environment you launch it from. The single most important thing: activate your virtual environment before running claude.
python -m venv .venv
source .venv/bin/activate # macOS/Linux
.venv\Scripts\activate # Windows PowerShell
# Verify Claude uses the right Python
claude # then ask: "which python are you using?"
Put this in .claude/hooks/UserPromptSubmit.sh to auto-activate every session:
#!/bin/bash
if [[ -f ".venv/bin/activate" ]]; then
source .venv/bin/activate
elif [[ -f "venv/bin/activate" ]]; then
source venv/bin/activate
fi
conda activate myenv
claude
# Or with mamba:
mamba activate myenv
claude
pip install uv
uv venv
source .venv/bin/activate
uv pip install -r requirements.txt
claude # Claude can also run "uv run pytest" etc.
Drop this in your project root as CLAUDE.md and customize it. Claude reads this every session — good setup here saves minutes every time you start.
Claude Code's most powerful Python workflow is test-driven development. The loop is tight: write a failing test, implement the code, verify green.
Prompt: "Write a pytest test for a function calculate_discount(price, percent) that validates inputs and handles edge cases. Don't implement the function yet — just the tests."
Prompt: "Run the tests. Implement calculate_discount in src/pricing.py to make all tests pass. Use strict type annotations."
Prompt: "The tests are passing. Refactor calculate_discount to use a dataclass for the return type. Run tests again after."
Create reusable test data factories.
"Add a pytest fixture in conftest.py that creates a sample User with related Orders. Use factory_boy if available."
Cover edge cases efficiently.
"Rewrite this test using @pytest.mark.parametrize to cover: zero price, negative price, 100% discount, and decimal percents."
Isolate tests from network calls.
"Add pytest-mock patches for the Stripe API calls in tests/test_billing.py. The mock should return a PaymentIntent fixture."
Diagnose and fix without changing intent.
"Run pytest -x, read the full traceback, identify the root cause, and fix it. Do not change the test's intent."
Find and fill missing coverage.
"Run pytest --cov=src --cov-report=term-missing. Write tests for any function under 80% coverage."
Test async code with pytest-asyncio.
"Convert the tests in test_api.py to use pytest-asyncio. The functions being tested are all async def."
"Create a Django model for a BlogPost with: title (unique, 200 chars), slug (auto-generated from title), body (TextField), published_at (nullable), author (ForeignKey to User), tags (ManyToMany). Then generate the migration."
"Add a class-based ListView for BlogPost that: filters by tag query param, paginates by 10, and uses a template at templates/blog/list.html. Wire it to urls.py at /blog/."
"Create a DRF ViewSet for BlogPost with: list (public), retrieve (public), create/update/destroy (staff only). Use a HyperlinkedModelSerializer. Register it with the router in api/urls.py."
"Write a management command in management/commands/import_posts.py that reads a JSON file path from args, validates each entry against the BlogPost schema, and creates or updates records. Add --dry-run flag."
"Register BlogPost in admin.py with: list_display showing title, author, published_at; list_filter on tags and published status; search_fields on title and body; inline for Comments."
INSTALLED_APPS, database engine, and key model names. Claude will avoid generating migrations for third-party apps and understand your project's relationships.
"Create a FastAPI router for /items/ with: GET (list with pagination), POST (create), GET /{id}, PUT /{id}, DELETE /{id}. Use Pydantic v2 models for request/response. Store in a SQLAlchemy 2.0 session (dependency-injected)."
"Add JWT authentication to the FastAPI app: /auth/token endpoint that accepts username+password, returns JWT; a get_current_user dependency using python-jose; apply the dependency to all /items/ routes."
"Add a background task that sends a confirmation email when a new Item is created. Use FastAPI's BackgroundTasks. The email function should be in services/email.py."
"Convert the SQLAlchemy session to async using asyncpg. Update all repository functions to use async def and await. Keep the sync session available for Alembic migrations."
"Write pytest tests for all /items/ endpoints using TestClient. Include: happy path, validation errors, 404 cases, and auth failures. Use a SQLite in-memory database fixture."
"Refactor the Flask app to use blueprints. Create blueprints for: auth (/auth), api (/api/v1), admin (/admin). Each blueprint should have its own routes.py, models.py, and forms.py."
"Add a User model using Flask-SQLAlchemy with: id (UUID primary key), email (unique, indexed), password_hash, created_at, is_active. Add a classmethod for creating users with hashed passwords."
"Create a WTForms form for user registration with: email (Email validator), password (Length 8-128), confirm_password (EqualTo). Add server-side validation that checks email uniqueness."
"Write pytest tests using Flask's test client. Add a fixture that creates a fresh in-memory SQLite database for each test. Include tests for the auth blueprint: register, login, logout, protected route."
Claude Code is a strong data science assistant — it reads CSV/Parquet files, writes and refines analysis code, and can run scripts directly.
# Step 1: Explore the data
"Read data/sales_2025.csv. Describe its shape, dtypes, missing value percentages, and statistical summary for numeric columns. Flag any data quality issues."
# Step 2: Clean and transform
"Write a pandas pipeline in src/clean.py that: drops rows where revenue is null, fills missing category with 'Unknown', converts date_str to datetime, and exports to data/sales_clean.parquet."
# Step 3: Analyze
"Read data/sales_clean.parquet. Group by region and quarter, compute total_revenue, avg_order_value, and order_count. Sort by total_revenue desc. Export to reports/by_region.csv."
# Step 4: Visualize
"Create a matplotlib figure with 2 subplots: (1) revenue by region as a bar chart, (2) revenue trend over quarters as a line chart per region. Save to reports/revenue_analysis.png at 150 DPI."
# Step 5: Optimize slow code
"Profile process_large_file() using cProfile. Show the top 10 slowest functions. Then rewrite it using vectorized pandas operations and measure the speedup."
Ask Claude to use modern pandas method chaining.
"Rewrite the data transformations in analysis.py using pandas method chaining (no intermediate variables)."
Convert slow pandas code to Polars.
"Convert the pandas code in etl.py to Polars lazy API for 10x speed on large CSVs."
SQL on DataFrames for complex aggregations.
"Rewrite the multi-join aggregation in report.py using DuckDB's Python API operating on the pandas DataFrames."
Convert exploratory notebook to production.
"Convert analysis.ipynb to a clean Python script. Extract functions, add type annotations, and add argparse for the input/output paths."
Claude Code writes fully typed Python by default when you ask for it — and it can retrofit annotations to legacy codebases.
# Annotate a whole module
"Add complete type annotations to every function in src/utils.py. Use TypeVar for generic functions. Run mypy after and fix any errors."
# Fix mypy errors
"Run mypy src/ and share the error output. Fix all errors without changing the runtime behavior."
# Strict mode
"Enable mypy strict mode in pyproject.toml. Fix all resulting errors in src/. External packages can use type: ignore[import] if stubs don't exist."
# Complex types
"Replace the Dict[str, Any] return type in parse_config() with a TypedDict that documents all expected keys and their types."
# Claude understands modern syntax
"Use Python 3.12 type syntax: X | Y unions (not Optional[X]), list[int] (not List[int]), dict[str, int] (not Dict[str, int]). Update all annotations in the codebase."
# Protocols
"Replace the duck-typed Processor class with a typing.Protocol. Any class implementing process(data: bytes) -> str should satisfy it without inheriting."
# TypeGuard
"Add a TypeGuard function is_valid_user(obj: object) -> TypeGuard[User] to validators.py that narrows the type for the rest of the branch."
# Stack trace → root cause
"Here's a stack trace from production: [paste trace]. Read the relevant source files and identify the root cause. Propose a fix with a regression test."
# Reproduce first
"I'm getting an intermittent KeyError in process_queue(). Add logging to reproduce the issue. Once we can reproduce it consistently, write a failing test."
# Performance debugging
"The API response time for /api/users/ is 2s. Add Django Debug Toolbar or use django-silk to profile the query count. Report N+1 issues and fix them with select_related/prefetch_related."
# Memory leak
"The process RSS grows by 50MB per hour. Use tracemalloc to snapshot memory at startup and after 1000 requests. Diff the snapshots and identify what's accumulating."
# Async debugging
"The asyncio event loop is blocking somewhere. Add asyncio.set_event_loop_debug(True) and look for coroutines taking >0.1s. Report the culprit."
def f(x=[]): → shared across calls)== not is)SettingWithCopyWarning and when .copy() is needed__slots__ vs dataclasses vs attrs for performance-sensitive classes| Category | Prompt |
|---|---|
| Setup | "Set up this repo: create a .venv, install requirements.txt, run the test suite, and tell me how many tests pass." |
| Setup | "Add a pyproject.toml with ruff, mypy, and pytest config. Include ruff rules I, E, F, and B." |
| Testing | "Write pytest tests for all public functions in src/auth.py. Aim for 90%+ branch coverage." |
| Testing | "Add a pytest.ini or pyproject.toml section that sets testpaths=tests, addopts=-x --tb=short -q." |
| Testing | "Generate property-based tests using Hypothesis for the parse_amount() function." |
| Refactoring | "Refactor the 200-line process() function into smaller functions. Each should have a single responsibility and be independently testable." |
| Refactoring | "Replace the manual singleton pattern in cache.py with functools.cache or functools.lru_cache." |
| Refactoring | "Replace all string formatting with f-strings. Use % formatting only for logging calls (lazy evaluation)." |
| Async | "Convert the synchronous HTTP calls in fetcher.py to use httpx async client. Use asyncio.gather() for concurrent fetches." |
| Async | "Add a rate limiter to the async fetch loop so it never exceeds 10 requests per second." |
| Performance | "Profile the import time of this package with python -X importtime and reduce it by moving slow imports inside functions." |
| Performance | "Replace the nested loop in compute_matrix() with NumPy broadcasting. Show me the speedup with timeit." |
| Data | "Read the schema of data/users.parquet. Generate a pandas pipeline that validates all rows against the expected types." |
| Data | "Build a data quality report: for each column, show dtype, % missing, top 5 values, and flag any outliers beyond 3 std dev." |
| CLI | "Add a Click CLI to this script with: --input path, --output path, --verbose flag, and --format [json|csv] option." |
| CLI | "Add shell completion for the Click CLI and show me how to install it for bash and zsh." |
| Packaging | "Set up this package for publishing on PyPI: pyproject.toml with all required metadata, LICENSE file, and a GitHub Actions workflow for publish-on-tag." |
| Security | "Run bandit -r src/ and fix all HIGH severity issues. Explain the risk of each fix." |
| Docs | "Add Google-style docstrings to every public function in src/. Include Args, Returns, Raises, and an Example section." |
| Docs | "Generate a Sphinx conf.py + index.rst using autodoc. Build the HTML docs and report any missing docstrings." |
| Django | "Add Django Channels WebSocket support for real-time notifications. Use Redis channel layer." |
| Django | "Audit all raw SQL queries and .extra() calls in the codebase. Replace them with ORM equivalents." |
| FastAPI | "Add OpenTelemetry tracing to all FastAPI endpoints. Export to OTLP. Add a span for each database query." |
| FastAPI | "Generate a Pydantic v2 settings class that loads from .env with validation. Inject it as a FastAPI dependency." |
| Debugging | "Add structured logging with structlog to replace all print() statements. Include correlation IDs for HTTP requests." |
| Debugging | "Run the test suite under pytest-timeout with a 5-second limit. Identify any tests that are too slow and fix them." |
| Migration | "Migrate from setup.py + requirements.txt to pyproject.toml using hatchling. Preserve all package metadata." |
| Migration | "Upgrade the codebase from Python 3.9 to 3.12 syntax: match statements, tomllib, TypeAlias, etc." |
| AI/ML | "Add a Pydantic-AI agent that uses Claude claude-sonnet-4-6 to classify the intent of user messages in intents.py." |
| AI/ML | "Profile the model inference loop. Identify where batching would help and implement it with torch.no_grad()." |
Yes — Claude Code inherits the shell environment you launch it from. Activate your virtualenv first (source .venv/bin/activate or conda activate myenv), then run claude. Claude uses the activated Python and all installed packages. You can also auto-activate via a Claude hook so the venv is always active. See the setup section above for the hook code.
Claude Code integrates naturally with pytest. The most effective pattern: "Run pytest and fix any failing tests" — Claude runs the suite, reads error output, identifies the root cause, and implements a fix. For TDD: "Write a failing test for [feature], then implement the code to make it pass." Add your pytest command to CLAUDE.md (pytest -x --tb=short -q) so Claude uses consistent flags.
Yes — Claude understands Django's ORM, views, templates, forms, signals, management commands, migrations, and the admin. Add your INSTALLED_APPS and key models to CLAUDE.md for best results. Claude generates migrations correctly, avoids touching third-party app migrations, and understands Django's project/app structure. See the Django patterns section above for copy-paste prompts.
Claude writes fully typed Python by default when asked. It understands mypy, pyright, and Pytype. To retrofit a legacy codebase: "Add complete type annotations to every function in src/. Run mypy after and fix any errors." Claude uses modern Python 3.10+ union syntax (X | Y not Optional[X]), TypedDict, Protocol, TypeVar, and TypeGuard correctly.
Claude Code can read and edit .ipynb files directly. Useful prompts: "Convert this notebook to a clean Python script", "Add docstring cells explaining each analysis step", "Extract the data processing into reusable functions in utils.py." For large refactors, export to .py first with jupyter nbconvert --to script — Claude is more effective on plain Python files for complex restructuring.
Essential items: (1) Python version and venv activation command, (2) test command with flags (pytest -x --tb=short), (3) lint/format command (ruff check . && ruff format --check .), (4) type check command (mypy src/), (5) dev server command, (6) project structure overview, (7) naming conventions, (8) directories Claude must not touch (migrations/, .env). The CLAUDE.md template above covers all of this — customize it in 5 minutes.
Claude handles the full data science workflow: exploration → cleaning → transformation → analysis → visualization. Effective openers: "Read data/sales.csv, describe its shape and data quality issues", then "Write a pandas cleaning pipeline for the issues you found." For performance: "Rewrite this loop using vectorized NumPy operations" or "Convert the pandas code to Polars lazy API."