home / skills / yldgio / codereview-skills / fastapi

fastapi skill

/skills/fastapi

This skill helps design and review FastAPI endpoints with Pydantic, DI, and async patterns for secure, scalable APIs.

npx playbooks add skill yldgio/codereview-skills --skill fastapi

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
3.1 KB
---
name: fastapi
description: FastAPI endpoint design, Pydantic validation, dependency injection, and async patterns
---

## FastAPI Code Review Rules

### Security (Critical)
- Validate and sanitize all inputs to prevent injection attacks
- Use `OAuth2PasswordBearer` or similar for auth
- Rate limit sensitive endpoints
- Never log sensitive data (passwords, tokens)
- Implement CORS properly with `CORSMiddleware`
- Use CSRF protection for cookie-based auth
- Validate content types and sanitize HTML to prevent XSS
- Use security headers (HSTS, CSP, X-Frame-Options)
- Always validate user input in path operations and request bodies
- Never use HTML comments (`<!-- -->`) in production code

### Endpoint Design
- Use appropriate HTTP methods (GET for reads, POST for creates, etc.)
- Return appropriate status codes (201 for create, 204 for delete, etc.)
- Use path parameters for resource identifiers, query params for filtering
- Group related endpoints with `APIRouter` and tags
- Document endpoints with clear docstrings
- Use OpenAPI metadata (summary, description, response descriptions)
- Provide detailed response model documentation
- Implement API versioning (URL prefix recommended)
- Mark deprecated endpoints with `deprecated=True`

### Pydantic Models
- Use Pydantic models for request body validation (not raw dicts)
- Define explicit response models with `response_model` parameter
- Use `Field()` for validation constraints (min/max, regex, etc.)
- Separate input models from output models (Create vs Response)
- Use type annotations for all endpoint arguments and return types
- Return only JSON-serializable results
- Use `model_config` for Pydantic v2 configuration

### Dependency Injection
- Use `Depends()` for shared logic (auth, db sessions, etc.)
- Database sessions should be dependencies, not global
- Close resources properly (use context managers or finally)

### Async
- Use `async def` for I/O-bound endpoints
- Don't mix sync and async database calls
- Use `asyncio.gather()` for parallel async operations
- Avoid blocking calls in async functions (use `run_in_executor`)

### Advanced Async Patterns
- Use async context managers (`async with`) for managing async resources (DB sessions, HTTP clients)
- Use `BackgroundTasks` for work that should outlive the response
- Use startup/shutdown events (`@app.on_event("startup"/"shutdown")`) to initialize/cleanup shared async resources
- Apply concurrency limits with `asyncio.Semaphore` when calling external services
- For streaming responses or WebSockets, implement backpressure-aware designs
- For more patterns, see [FastAPI Async Documentation](https://fastapi.tiangolo.com/async/)

### Error Handling
- Use `HTTPException` for expected errors with proper status codes
- Create custom exception handlers for domain exceptions
- Don't expose internal error details to clients
- Log errors with context (request ID, user, etc.)

### Project Structure
- Organize by feature or layer (routers, models, services, dependencies)
- Keep routers thin - business logic in services
- Separate Pydantic models from database models
- Use a `dependencies` module for reusable dependencies
- Create `config.py` for settings management

Overview

This skill captures practical rules and patterns for designing FastAPI endpoints, Pydantic validation, dependency injection, and async patterns. It focuses on secure, maintainable API design and clear separation of concerns for production-ready applications. The guidance balances security, performance, and developer ergonomics.

How this skill works

The skill inspects endpoint design, input/output validation, dependency usage, and async behaviors to surface issues and recommend best practices. It evaluates security controls (auth, CORS, headers), correct HTTP semantics, Pydantic model usage, dependency lifecycle, and async safety. It flags risky patterns and suggests concrete fixes and improvements.

When to use it

  • When reviewing FastAPI projects for security and correctness before release
  • When designing new endpoints and deciding request/response models
  • When migrating sync code to async or integrating async libraries
  • When creating reusable dependencies like DB sessions or auth handlers
  • When setting project structure, OpenAPI docs, and versioning strategy

Best practices

  • Validate and sanitize all inputs; use Pydantic models and Field() constraints
  • Use OAuth2PasswordBearer or similar and avoid logging sensitive data
  • Group routes with APIRouter, document with OpenAPI metadata, and version APIs
  • Implement dependencies with Depends(), manage DB sessions via context managers
  • Prefer async def for I/O endpoints; avoid blocking calls and mixed sync/async DB calls
  • Use startup/shutdown events and BackgroundTasks for shared resources and long-running work

Example use cases

  • Code review checklist to ensure endpoints use correct methods, status codes, and models
  • Refactoring a monolithic router into feature-based routers with clear dependencies
  • Converting blocking database calls to async patterns and applying concurrency limits
  • Hardening an API by adding CORS, CSRF for cookies, security headers, and rate limiting
  • Designing response models that separate internal fields from client-facing data

FAQ

Should I always use async def for endpoints?

Prefer async def for I/O-bound work. If your stack or DB client is sync, either use sync endpoints or adopt async-compatible drivers to avoid blocking the event loop.

How do I prevent sensitive data leaks in logs and responses?

Never log secrets or tokens. Use separate output models for responses, redact sensitive fields, and sanitize any user-provided content before logging.

How to manage DB sessions correctly?

Provide DB sessions as Depends(), use context managers or try/finally to close sessions, and avoid global session objects.