You've set up Claude Code or Cursor. You ask it to write a FastAPI endpoint. It comes back with dict everywhere, bare except Exception , and a function that mutates a list default argument. It works , but it's not Python — it's Python-shaped code that will hurt you in six months. The fix is a CLAUDE.md that tells the model exactly what "good Python" means on your project. Here are 13 rules that turn AI-generated Python from plausible to production-ready. 1. Always use type hints — including Annotated and TypeVar # Bad def get_user ( user_id ): ... # Good from typing import Annotated from uuid import UUID UserId = Annotated [ UUID , " user primary key " ] def get_user ( user_id : UserId ) -> User : ... Enter fullscreen mode Exit fullscreen mode Rule for CLAUDE.md: "All functions must have fully annotated signatures. Use Annotated for domain-specific constraints. Define TypeVar for generic utilities." 2. Use Pydantic models, not raw dicts Dicts are untyped bags. Pydantic models are contracts.…