Agent RulesAgent Rules
Builder
Options
Browse all rules by language and framework
Templates
Pre-built rule sets ready to use
Popular Rules
Top community-ranked rules leaderboard
GuidesAnalyzePricingContact
Builder
OptionsTemplatesPopular Rules
GuidesAnalyzePricingContact

Product

  • Builder
  • Templates
  • Browse Rules
  • My Library

Learn

  • What are AI Agent Rules?
  • Guides
  • FAQ
  • About

Resources

  • Terms
  • Privacy Policy
  • Pricing
  • Contact
  • DMCA Policy

Support

Help keep this project free.

Agent RulesAgent Rules Builder
© 2026 Aurora Algorithm Inc.
Back to Templates

Python + FastAPI

Complete rules for Python backend development with FastAPI. Covers async/await patterns, Pydantic v2 models, dependency injection, SQLAlchemy integration, background tasks, WebSocket support, and production deployment practices.

pythonPython/fastapiFastAPI
python
fastapi
pydantic
async
api
sqlalchemy
rest
Customize in Builder

Details

Language
pythonPython
Framework
fastapiFastAPI

Rules Content

AGENTS.md
Edit in Builder

Python + FastAPI Agent Rules

Project Context

You are building a Python backend with FastAPI, Pydantic v2, and async SQLAlchemy 2.0. The architecture uses APIRouter for route organization, dependency injection for cross-cutting concerns, and strict type hints throughout.

Code Style & Structure

- Use Python 3.12+ type hints on all function signatures and variables. Run `mypy --strict` or `pyright` in CI.
- Use f-strings for interpolation. Use `pathlib.Path` for file operations.
- Follow PEP 8. Format with `ruff format`. Lint with `ruff check --select ALL`.
- Keep route handlers under 15 lines. Extract business logic to service functions.

Project Structure

```
app/
main.py # create_app(): mounts routers, registers middleware, exception handlers
api/
v1/
users.py # APIRouter(prefix='/users', tags=['Users'])
auth.py
dependencies.py # get_db, get_current_user, get_pagination
core/
config.py # Settings(BaseSettings) with Pydantic
security.py # JWT creation, verification, password hashing
models/ # SQLAlchemy ORM models
schemas/ # Pydantic request/response schemas per resource
services/ # Business logic — no FastAPI/HTTP imports
repositories/ # Data access — accept AsyncSession, return domain objects
exceptions.py # Custom HTTPException subclasses
middleware.py # Request ID, logging, timing middleware
```

FastAPI Patterns

- Group routes with `APIRouter`. Mount with `app.include_router(router, prefix='/api/v1')`.
- Always declare `response_model=` on route decorators for automatic response serialization and OpenAPI docs.
- Use `status.HTTP_201_CREATED`, `status.HTTP_204_NO_CONTENT` explicitly — never hardcode integers.
- Use `BackgroundTasks` for post-response work (sending emails, audit logging) that does not affect the response.
- Register exception handlers with `app.add_exception_handler(ExceptionClass, handler)` for consistent error responses.
- Use `Annotated` for dependency injection: `CurrentUser = Annotated[User, Depends(get_current_user)]`.

Pydantic v2

- Inherit from `BaseModel` for all schemas. Use `model_config = ConfigDict(from_attributes=True)` for ORM compatibility.
- Define separate schema classes: `UserCreate`, `UserUpdate`, `UserRead`, `UserInDB` — never reuse one schema for all operations.
- Use `model_validator(mode='after')` for cross-field validation. Use `field_validator` for per-field normalization.
- Use `Field(title=..., description=..., examples=[...])` on public API fields for OpenAPI documentation quality.
- Use `SecretStr` for password fields. Use `EmailStr` (from `pydantic[email]`) for email fields.
- Prefer `model.model_dump(exclude_unset=True)` for partial update payloads to avoid overwriting with defaults.

Dependency Injection

- Create `get_db()` as an async generator: `async def get_db(): async with AsyncSessionLocal() as session: yield session`.
- Use `Depends` for all shared concerns: DB session, current user, pagination params, permission checks.
- Write permission dependencies that raise `HTTPException(403)` on insufficient access.
- Chain dependencies: `Annotated[User, Depends(get_current_active_user)]` builds on `Depends(get_current_user)`.
- Use `lifespan` context manager in `create_app()` for startup/shutdown: open DB pool, close on shutdown.

Async Patterns

- Use `async def` for all route handlers and any function that performs I/O.
- Use `asyncio.gather(*coroutines)` for concurrent independent I/O operations.
- Never call blocking code (`requests.get`, `time.sleep`, `open()`) in async context. Use `run_in_executor` or `aiofiles`.
- Use async context managers (`async with`) for resource acquisition and release.

Database (SQLAlchemy 2.0 Async)

- Use `AsyncSession` with `expire_on_commit=False` to avoid lazy-load errors after commit.
- Use `select(Model).where(...).options(selectinload(Model.relation))` for eager-loading relations.
- Wrap multi-step mutations in `async with session.begin():` for automatic commit/rollback.
- Use `await session.execute(statement)` and `.scalars().all()` for multi-row queries.
- Generate migrations with Alembic. Use async engine in `env.py`. Write reversible `downgrade()` functions.

Error Handling

- Define custom exception classes: `class ResourceNotFoundError(HTTPException): def __init__(self, resource: str): super().__init__(404, f'{resource} not found')`.
- Register a handler for `RequestValidationError` that returns `422` with field-level error details.
- Log unexpected `500` errors with `structlog` or `loguru` including `request_id`, `path`, and full traceback.
- Return `{ "detail": [{ "loc": [...], "msg": "...", "type": "..." }] }` for validation errors (FastAPI default format).

Security

- Hash passwords with `passlib[bcrypt]` at cost factor 12. Use `CryptContext(schemes=['bcrypt'])`.
- Use `python-jose[cryptography]` or `authlib` for JWT. Sign with RS256 in production.
- Validate `exp`, `iss`, and `aud` claims. Raise `401` on invalid tokens.
- Apply `slowapi` rate limiting on auth endpoints: `@limiter.limit('5/minute')`.
- Configure CORS with explicit `allow_origins` — never `['*']` with `allow_credentials=True`.

Testing

- Use `pytest-asyncio` with `asyncio_mode = "auto"` in `pyproject.toml`.
- Use `httpx.AsyncClient` with `ASGITransport(app=app)` for async route tests — no real server needed.
- Use a real test database. Apply Alembic migrations in test setup. Truncate tables between tests.
- Create test data with `factory_boy` async factories. Never hardcode UUIDs or emails.
- Test dependency overrides: `app.dependency_overrides[get_db] = get_test_db` per test or module.

Related Templates

python

Python + Django

Django web development with class-based views, ORM best practices, and DRF.

python

Python + Flask

Lightweight Python web development with Flask and extensions.

python

Python + ML/Data Science

Machine learning and data science with Python, PyTorch, and scikit-learn.