Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Fastapi

ASecurity

Expert skill for FastAPI web framework development. Covers ASGI/Starlette foundation, Pydantic v2 integration, dependency injection, path operations, automatic OpenAPI generation, async/await patterns, middleware, security (OAuth2, JWT), testing (TestClient, httpx), SQLAlchemy/SQLModel integration, and deployment. WHEN: \"FastAPI\", \"Starlette\", \"ASGI\", \"Pydantic\", \"Depends\", \"APIRouter\", \"path operation\", \"response_model\", \"OpenAPI auto-docs\", \"Swagger UI\", \"FastAPI middle...

4 stars
0 votes
0 copies
0 views
Added 9/24/2026
databasespythonrustgosqlfastapidockertestingdebugginggitapi

Works with

cliapi

Security Analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned 9/24/2026

$npx -y skills add chrishuffman5/domain-expert --skill fastapi --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Fastapi?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Fastapi
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/chrishuffman5-fastapi/badge)](https://www.skillsdirectory.com/skills/chrishuffman5-fastapi)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: fastapi
description: "Expert skill for FastAPI web framework development. Covers ASGI/Starlette foundation, Pydantic v2 integration, dependency injection, path operations, automatic OpenAPI generation, async/await patterns, middleware, security (OAuth2, JWT), testing (TestClient, httpx), SQLAlchemy/SQLModel integration, and deployment. WHEN: \"FastAPI\", \"Starlette\", \"ASGI\", \"Pydantic\", \"Depends\", \"APIRouter\", \"path operation\", \"response_model\", \"OpenAPI auto-docs\", \"Swagger UI\", \"FastAPI middleware\", \"FastAPI dependency injection\", \"FastAPI testing\", \"TestClient\", \"BackgroundTasks\", \"SQLModel\", \"uvicorn\", \"FastAPI WebSocket\", \"FastAPI security\", \"OAuth2PasswordBearer\". Do NOT use for general Python scripting, automation, or CLI-tool questions unrelated to the FastAPI framework — that's the `cli-scripting` plugin's `python` skill."
license: MIT
---

# FastAPI

This skill covers FastAPI development. FastAPI is a modern, high-performance Python web framework built on Starlette (ASGI) and Pydantic v2. It provides automatic OpenAPI documentation, type-driven request validation, a powerful dependency injection system, and first-class async support. FastAPI follows rolling 0.x releases -- there is no version-specific reference material.

## How to Approach Tasks

1. **Classify** the request:
   - **Architecture** -- Load `references/architecture.md` for ASGI internals, Starlette foundation, Pydantic v2 models, dependency injection mechanics, request lifecycle, OpenAPI generation, response handling
   - **Best practices** -- Load `references/best-practices.md` for project structure, repository/service pattern, auth flows, database patterns, testing, deployment, caching, error handling
   - **Troubleshooting** -- Load `references/diagnostics.md` for 422 validation errors, Pydantic v1-to-v2 migration, async pitfalls, dependency resolution failures, performance profiling

2. **Gather context** -- Check Python version (3.11+ recommended), FastAPI version, Pydantic v1 vs v2, sync vs async database driver, deployment target (Docker, bare metal, serverless).

3. **Load context** -- Read the relevant reference file before answering.

4. **Analyze** -- Apply FastAPI-specific reasoning. Consider Pydantic model design, dependency graph complexity, async vs sync trade-offs, and OpenAPI schema impact.

5. **Recommend** -- Provide concrete Python code examples with explanations. Always qualify trade-offs.

6. **Verify** -- Suggest validation steps: run tests with `pytest`, check OpenAPI schema at `/docs`, verify dependency resolution, confirm async behavior.

## Core Architecture

### ASGI and Starlette Foundation

FastAPI is a Starlette application. Every `FastAPI()` instance inherits Starlette's ASGI interface, routing, middleware stack, and request/response classes. ASGI replaces WSGI by supporting long-lived connections (WebSockets, SSE) and native async.

```python
from fastapi import FastAPI, Request

app = FastAPI()

# Direct access to Starlette primitives
@app.get("/raw")
async def raw_access(request: Request) -> dict:
    return {
        "method": request.method,
        "client": request.client,
        "scope_type": request.scope["type"],
    }
```

**Starlette classes exposed by FastAPI:** `APIRouter` (from `Router`), `Request`/`Response`, `BackgroundTasks`, `WebSocket`, `StaticFiles`, `TestClient`.

### Pydantic v2 Integration

FastAPI uses Pydantic v2 for all validation and serialization. The v2 engine is Rust-based (`pydantic-core`), providing 5-50x faster validation than v1.

```python
from pydantic import BaseModel, Field, field_validator, model_validator, ConfigDict
from typing import Annotated, Self

class UserCreate(BaseModel):
    model_config = ConfigDict(str_strip_whitespace=True)

    username: Annotated[str, Field(min_length=3, max_length=50, pattern=r"^[a-z0-9_]+$")]
    email: str
    age: Annotated[int, Field(ge=18, le=120)]

class OrderCreate(BaseModel):
    quantity: int
    unit_price: float
    total: float

    @field_validator("quantity")
    @classmethod
    def quantity_positive(cls, v: int) -> int:
        if v <= 0:
            raise ValueError("quantity must be positive")
        return v

    @model_validator(mode="after")
    def check_total(self) -> Self:
        expected = self.quantity * self.unit_price
        if abs(self.total - expected) > 0.01:
            raise ValueError(f"total {self.total} does not match {expected:.2f}")
        return self
```

**Key v2 changes:** `model_config = ConfigDict(...)` replaces inner `Config` class. `from_attributes=True` replaces `orm_mode=True`. `model_dump()` replaces `dict()`. `Field(exclude=True)` for serialization control.

### Dependency Injection

FastAPI's DI system resolves dependencies per-request via `Depends()`. Dependencies are cached within the same request, support async, and compose into sub-dependency graphs.

```python
from fastapi import Depends, Query
from typing import Annotated

class PaginationParams:
    def __init__(self, page: int = Query(1, ge=1), size: int = Query(20, ge=1, le=100)):
        self.page = page
        self.size = size
        self.offset = (page - 1) * size

Pagination = Annotated[PaginationParams, Depends()]

# Yield dependencies for resource management (DB sessions)
async def get_db() -> AsyncGenerator[AsyncSession, None]:
    async with AsyncSessionLocal() as session:
        try:
            yield session
            await session.commit()
        except Exception:
            await session.rollback()
            raise

DB = Annotated[AsyncSession, Depends(get_db)]

# Router-level dependencies apply to all routes
router = APIRouter(prefix="/admin", dependencies=[Depends(require_admin)])
```

### Path Operations

```python
from fastapi import APIRouter, Path, Query, Body, status

router = APIRouter(prefix="/items", tags=["items"])

@router.get("/{item_id}", response_model=ItemRead, status_code=200)
async def get_item(
    item_id: Annotated[int, Path(ge=1)],
    include_deleted: Annotated[bool, Query()] = False,
) -> ItemRead:
    ...

@router.post("/", status_code=status.HTTP_201_CREATED)
async def create_item(item: ItemCreate, db: DB) -> ItemRead:
    ...
```

**Parameter sources:** Path params from URL template, Query params from simple types not in the path, Body from Pydantic models, plus `Header()`, `Cookie()`, `Form()`, `File()`.

**Response models:** Use `response_model=` parameter for explicit type narrowing and field filtering, or return type annotations for cleaner signatures. `response_model` runs automatic validation; return type annotations do not.

### OpenAPI Auto-Generation

FastAPI generates OpenAPI 3.1 specs from your code. Interactive docs at `/docs` (Swagger UI) and `/redoc`.

```python
app = FastAPI(
    title="My API",
    version="1.0.0",
    docs_url="/api/docs",
    redoc_url="/api/redoc",
    openapi_url="/api/openapi.json",
)

# Hide internal endpoints
@app.get("/internal/metrics", include_in_schema=False)
async def metrics(): ...

# Disable docs in production
app = FastAPI(docs_url=None, redoc_url=None)
```

### Async/Await

```python
# async def: for awaitable I/O (async DB, httpx, aiofiles)
@app.get("/async")
async def async_endpoint(db: DB) -> list[ItemRead]:
    result = await db.execute(select(Item))
    return result.scalars().all()

# def: for sync/blocking code -- FastAPI runs these in a threadpool automatically
@app.get("/sync")
def sync_endpoint() -> dict:
    return requests.get("https://external.api/data").json()
```

**Rule:** Use `async def` with awaitable I/O. Use `def` for blocking libraries (requests, psycopg2, boto3). Never call blocking I/O inside `async def` without wrapping in a threadpool.

### Middleware

```python
from fastapi.middleware.cors import CORSMiddleware
from starlette.middleware.base import BaseHTTPMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://app.example.com"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Custom middleware
class RequestIDMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request, call_next):
        request_id = str(uuid.uuid4())
        request.state.request_id = request_id
        response = await call_next(request)
        response.headers["X-Request-ID"] = request_id
        return response

app.add_middleware(RequestIDMiddleware)
```

For high-throughput scenarios, write pure ASGI middleware instead of `BaseHTTPMiddleware` (which buffers responses).

### Security

FastAPI provides `OAuth2PasswordBearer`, `APIKeyHeader`, `APIKeyQuery`, and `SecurityScopes` for building auth flows.

```python
from fastapi.security import OAuth2PasswordBearer
import jwt

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/auth/token")

async def get_current_user(
    token: Annotated[str, Depends(oauth2_scheme)], db: DB
) -> User:
    payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
    user = await db.get(User, int(payload["sub"]))
    if not user:
        raise HTTPException(status_code=401, detail="Invalid credentials")
    return user

CurrentUser = Annotated[User, Depends(get_current_user)]
```

### Testing

```python
from fastapi.testclient import TestClient
from httpx import AsyncClient, ASGITransport

# Sync testing
client = TestClient(app)
response = client.get("/items/1")
assert response.status_code == 200

# Async testing
async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client:
    response = await client.post("/users/", json={"email": "test@example.com"})
    assert response.status_code == 201

# Dependency overrides for isolation
app.dependency_overrides[get_current_user] = lambda: mock_user
app.dependency_overrides[get_db] = lambda: test_session
```

### Database Integration

FastAPI works with async SQLAlchemy 2.0 (via `asyncpg`/`aiosqlite`) and SQLModel (Pydantic + SQLAlchemy hybrid).

```python
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker

engine = create_async_engine("postgresql+asyncpg://...", pool_size=20)
AsyncSessionLocal = async_sessionmaker(engine, expire_on_commit=False)
```

### Lifespan Events

```python
from contextlib import asynccontextmanager

@asynccontextmanager
async def lifespan(app: FastAPI):
    # Startup
    app.state.http_client = httpx.AsyncClient(timeout=30.0)
    yield
    # Shutdown
    await app.state.http_client.aclose()

app = FastAPI(lifespan=lifespan)
```

## Key Patterns

| Pattern | When to Use |
|---|---|
| `Depends()` with yield | Database sessions, HTTP clients, any resource needing cleanup |
| `Annotated[T, Depends()]` | Reusable dependency type aliases (cleaner signatures) |
| `response_model` | Filtering ORM objects, returning different type than function return |
| `APIRouter` with `prefix`/`tags` | Organizing routes by resource or domain |
| `BackgroundTasks` | Fire-and-forget tasks (email, audit log) after response |
| Sub-applications via `app.mount()` | Separate OpenAPI schemas per version |
| `include_router` with `prefix` | Single OpenAPI schema, grouped routes |

## Error Handling

```python
from fastapi import HTTPException
from fastapi.exceptions import RequestValidationError

# Raise HTTP errors
raise HTTPException(status_code=404, detail="Item not found")

# Custom exception handlers
@app.exception_handler(RequestValidationError)
async def validation_handler(request, exc):
    return JSONResponse(status_code=422, content={"errors": exc.errors()})
```

## Deployment

| Configuration | Command |
|---|---|
| Development | `uvicorn app.main:app --reload --port 8000` |
| Production (single) | `uvicorn app.main:app --host 0.0.0.0 --workers 1` |
| Production (multi-core) | `gunicorn app.main:app -w 4 -k uvicorn.workers.UvicornWorker` |
| Docker | Gunicorn + UvicornWorker, non-root user, multi-stage build |

**Worker formula:** `(2 * CPU_COUNT) + 1` for I/O-bound async apps.

## Anti-Patterns

1. **Blocking I/O in `async def`** -- Blocks the event loop. Use `def` (threadpool) or wrap with `anyio.to_thread.run_sync()`.
2. **Skipping `expire_on_commit=False`** -- Causes `MissingGreenlet` errors when accessing ORM attributes after commit in async context.
3. **Global mutable state** -- Each Gunicorn worker runs a separate process. Use Redis or database for shared state.
4. **`response_model` with ORM objects + missing `from_attributes=True`** -- Results in empty responses or validation errors.
5. **Overly deep dependency chains** -- FastAPI resolves the full graph per request. Keep dependency depth under 4-5 levels.

## Reference Files

Load these for deep knowledge on specific topics:

- `references/architecture.md` -- ASGI internals, Starlette foundation, Pydantic v2 (BaseModel, Field, validators, discriminated unions), dependency injection (Depends, yield, sub-dependencies, override), request lifecycle, OpenAPI generation, response model handling. **Load when:** architecture questions, Pydantic model design, DI mechanics, OpenAPI customization.
- `references/best-practices.md` -- Project structure, repository/service pattern, auth flows (JWT, OAuth2 scopes), database patterns (async SQLAlchemy, session management, Alembic), testing (TestClient, dependency overrides, database isolation), deployment (Uvicorn, Gunicorn workers, Docker), caching, background tasks, error handling. **Load when:** "how should I structure", auth implementation, database setup, testing strategy, deployment configuration.
- `references/diagnostics.md` -- Common errors (422 validation, Pydantic v1-to-v2 migration, async pitfalls, dependency resolution), debugging techniques, performance profiling, async database issues. **Load when:** troubleshooting errors, debugging validation failures, diagnosing performance problems.

Attribution

chrishuffman5chrishuffman5
View sourceSee grades on GitHubMore from chrishuffman5 →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Mysql Best Practices

MySQL development best practices for schema design, query optimization, and database administration

2481 votes

Jpa Patterns

Spring Boot中的JPA/Hibernate实体设计、关系、查询优化、事务、审计、索引、分页和连接池模式。

2456590 votes

Clickhouse Io

ClickHouse数据库模式、查询优化、分析和数据工程最佳实践,适用于高性能分析工作负载。

2456590 votes

Postgres Patterns

基于Supabase最佳实践的PostgreSQL数据库模式,用于查询优化、架构设计、索引和安全。

2456590 votes

Sql Pro

Master modern SQL with cloud-native databases, OLTP/OLAP

458250 votes
View all in databases →