Install any skill in seconds. Free to start, no credit card required.
Get Started Free →FastAPI web framework patterns. Triggers on: fastapi, api endpoint, dependency injection, pydantic model, openapi, swagger, starlette, async api, rest api, uvicorn.
.claude/skills/aiskillstore-python-fastapi-patterns/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-21 | ✗→✓ | ▲ Improved | 58% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 24% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 130% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 112% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 153% | 0% |
Modern async API development with FastAPI.
pythonfrom fastapi import FastAPI from contextlib import asynccontextmanager @asynccontextmanager async def lifespan(app: FastAPI): """Application lifespan - startup and shutdown.""" # Startup app.state.db = await create_db_pool() yield # Shutdown await app.state.db.close() app = FastAPI( title="My API", version="1.0.0", lifespan=lifespan, ) @app.get("/") async def root(): return {"message": "Hello World"}
pythonfrom pydantic import BaseModel, Field, EmailStr from datetime import datetime class UserCreate(BaseModel): """Request model with validation.""" name: str = Field(..., min_length=1, max_length=100) email: EmailStr age: int = Field(..., ge=0, le=150) class UserResponse(BaseModel): """Response model.""" id: int name: str email: EmailStr created_at: datetime model_config = {"from_attributes": True} # Enable ORM mode @app.post("/users", response_model=UserResponse, status_code=201) async def create_user(user: UserCreate): db_user = await create_user_in_db(user) return db_user
pythonfrom fastapi import Query, Path from typing import Annotated @app.get("/users/{user_id}") async def get_user( user_id: Annotated[int, Path(..., ge=1, description="User ID")], ): return await fetch_user(user_id) @app.get("/users") async def list_users( skip: Annotated[int, Query(ge=0)] = 0, limit: Annotated[int, Query(ge=1, le=100)] = 10, search: str | None = None, ): return await fetch_users(skip=skip, limit=limit, search=search)
pythonfrom fastapi import Depends from typing import Annotated async def get_db(): """Database session dependency.""" async with async_session() as session: yield session async def get_current_user( token: Annotated[str, Depends(oauth2_scheme)], db: Annotated[AsyncSession, Depends(get_db)], ) -> User: """Authenticate and return current user.""" user = await authenticate_token(db, token) if not user: raise HTTPException(status_code=401, detail="Invalid token") return user # Annotated types for reuse DB = Annotated[AsyncSession, Depends(get_db)] CurrentUser = Annotated[User, Depends(get_current_user)] @app.get("/me") async def get_me(user: CurrentUser): return user
pythonfrom fastapi import HTTPException from fastapi.responses import JSONResponse # Built-in HTTP exceptions @app.get("/items/{item_id}") async def get_item(item_id: int): item = await fetch_item(item_id) if not item: raise HTTPException(status_code=404, detail="Item not found") return item # Custom exception handler class ItemNotFoundError(Exception): def __init__(self, item_id: int): self.item_id = item_id @app.exception_handler(ItemNotFoundError) async def item_not_found_handler(request, exc: ItemNotFoundError): return JSONResponse( status_code=404, content={"detail": f"Item {exc.item_id} not found"}, )
pythonfrom fastapi import APIRouter # users.py router = APIRouter(prefix="/users", tags=["users"]) @router.get("/") async def list_users(): return [] @router.get("/{user_id}") async def get_user(user_id: int): return {"id": user_id} # main.py from app.routers import users, items app.include_router(users.router) app.include_router(items.router, prefix="/api/v1")
| Feature | Usage | |---------|-------| | Path param | @app.get("/items/{id}") | | Query param | def f(q: str = None) | | Body | def f(item: ItemCreate) | | Dependency | Depends(get_db) | | Auth | Depends(get_current_user) | | Response model | response_model=ItemResponse | | Status code | status_code=201 |
./references/dependency-injection.md - Advanced DI patterns, scopes, caching./references/middleware-patterns.md - Middleware chains, CORS, error handling./references/validation-serialization.md - Pydantic v2 patterns, custom validators./references/background-tasks.md - Background tasks, async workers, scheduling./scripts/scaffold-api.sh - Generate API endpoint boilerplate./assets/fastapi-template.py - Production-ready FastAPI app skeletonPrerequisites:
python-typing-patterns - Pydantic models and type hintspython-async-patterns - Async endpoint patternsRelated Skills:
python-database-patterns - SQLAlchemy integrationpython-observability-patterns - Logging, metrics, tracing middlewarepython-pytest-patterns - API testing with TestClient| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 11,883 | 8,301 | -30% | 1 | 1 | 0% | 2,277 | 2,822 | +24% | 0 | 0 | — |
case-02 | pass→pass | 5,094 | 4,966 | -3% | 1 | 1 | 0% | 994 | 2,290 | +130% | 0 | 0 | — |
case-03 | pass→pass | 5,705 | 3,728 | -35% | 1 | 1 | 0% | 1,019 | 2,160 | +112% | 0 | 0 | — |
case-04 | pass→pass | 5,066 | 5,917 | +17% | 1 | 1 | 0% | 982 | 2,487 | +153% | 0 | 0 | — |
case-05 | pass→pass | 3,576 | 4,661 | +30% | 1 | 1 | 0% | 636 | 2,202 | +246% | 0 | 0 | — |
case-06 | pass→pass | 6,712 | 5,929 | -12% | 1 | 1 | 0% | 1,440 | 2,683 | +86% | 0 | 0 | — |
case-07 | pass→pass | 9,906 | 6,262 | -37% | 1 | 1 | 0% | 1,826 | 2,543 | +39% | 0 | 0 | — |
case-08 | pass→pass | 11,148 | 8,899 | -20% | 1 | 1 | 0% | 2,035 | 3,015 | +48% | 0 | 0 | — |
case-09 | pass→pass | 4,889 | 5,607 | +15% | 1 | 1 | 0% | 884 | 2,360 | +167% | 0 | 0 | — |
case-10 | pass→pass | 5,386 | 4,135 | -23% | 1 | 1 | 0% | 1,196 | 2,184 | +83% | 0 | 0 | — |
case-11 | pass→pass | 8,002 | 10,458 | +31% | 1 | 1 | 0% | 1,509 | 3,618 | +140% | 0 | 0 | — |
case-12 | pass→pass | 8,261 | 5,274 | -36% | 1 | 1 | 0% | 1,557 | 2,323 | +49% | 0 | 0 | — |
case-13 | pass→pass | 6,032 | 5,524 | -8% | 1 | 1 | 0% | 1,152 | 2,372 | +106% | 0 | 0 | — |
case-14 | pass→pass | 3,396 | 2,864 | -16% | 1 | 1 | 0% | 618 | 1,866 | +202% | 0 | 0 | — |
case-15 | pass→pass | 10,342 | 6,303 | -39% | 1 | 1 | 0% | 1,988 | 2,627 | +32% | 0 | 0 | — |
case-16 | pass→pass | 6,933 | 5,672 | -18% | 1 | 1 | 0% | 1,339 | 2,438 | +82% | 0 | 0 | — |
case-17 | pass→pass | 9,154 | 8,673 | -5% | 1 | 1 | 0% | 1,629 | 2,935 | +80% | 0 | 0 | — |
case-18 | pass→pass | 3,644 | 4,869 | +34% | 1 | 1 | 0% | 610 | 2,217 | +263% | 0 | 0 | — |
case-19 | pass→pass | 3,526 | 3,813 | +8% | 1 | 1 | 0% | 567 | 1,987 | +250% | 0 | 0 | — |
case-20 | pass→pass | 8,311 | 8,451 | +2% | 1 | 1 | 0% | 1,588 | 2,915 | +84% | 0 | 0 | — |
case-21 | fail→pass | 8,702 | 6,949 | -20% | 1 | 1 | 0% | 1,709 | 2,704 | +58% | 0 | 0 | — |
case-22 | pass→pass | 5,876 | 5,676 | -3% | 1 | 1 | 0% | 1,094 | 2,446 | +124% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +5 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.