Python FastAPI & Pydantic v2 .cursorrules (.mdc)
Production-grade .cursorrules and .cursor/rules/*.mdc configuration for FastAPI and Pydantic v2. Enforce dependency injection, async I/O discipline, and strict typing.
---
description: Python FastAPI, Pydantic v2, and async service engineering standards
globs: **/*.py, api/**/*.py, routers/**/*.py
alwaysApply: false
---
# FastAPI & Python Standards
## Type Safety & Schema Validation
- All request bodies, path parameters, and responses MUST be declared with Pydantic v2 `BaseModel`.
- Always use Python 3.11+ type union syntax (`X | None` instead of `Optional[X]`).
- Use Pydantic v2 syntax: `.model_dump()` instead of deprecated `.dict()`, and `@field_validator`.
- Always declare explicit `response_model` on endpoints or use typed return annotations.
## Routing & Dependency Injection
- Organize routes using `APIRouter` with clear `tags` and `prefix` definitions.
- Inject database sessions and current user auth contexts using `Depends()`.
- Never use global database connections or unmanaged session singletons.
## Async & Concurrency Discipline
- Use `async def` for I/O-bound operations (database queries, external HTTP calls via `httpx`).
- Use standard `def` for synchronous CPU-bound operations or libraries without async support (e.g. pandas, Pillow).
- Always raise `HTTPException(status_code=..., detail=...)` with standard `status` constants.
https://cursor.pacebowl.com/rules/python-fastapi.html
Frequently Asked Questions & Implementation Notes
How do these rules handle Pydantic v2 migrations?
The rules enforce Pydantic v2 standards such as model_dump(), field_validator with @field_validator(mode='before'), and Field(...) constraints, completely avoiding deprecated Pydantic v1 methods like .dict().
When does the AI know to use async def vs standard def?
The rules clearly instruct Cursor to use 'async def' only for non-blocking I/O operations (database queries, network calls) and use standard 'def' with background worker offloading for CPU-bound tasks to prevent event-loop blocking.
How is dependency injection enforced?
Database sessions, authentication checks, and external API clients must be injected via FastAPI's Depends() rather than instantiated globally or inside route bodies.