Updated June 2026Cookbook18 min read

Claude fastapi skill: 10 backend endpoints you can ship

Ten production-ready FastAPI patterns — async CRUD, OAuth2 JWT login, Pydantic v2 models, an async SQLAlchemy session dependency, background tasks, global exception handlers, pytest with httpx.AsyncClient, pagination, a production Dockerfile, and API-key middleware — each as a single Claude prompt with the exact code the fastapi-templates skill writes.

Already know what skills are? Skip to the cookbook. First time? Read the explainer then come back. Need the install? It’s on the /skills/fastapi-templates page.

Editorial illustration: a Python async function glyph on the left flowing into a layered API stack glyph on the right, connected by a luminous teal arc, on a midnight navy background.
On this page · 21 sections
  1. What this skill does
  2. The cookbook
  3. Install + README
  4. Watch it built
  5. 01 · Async CRUD scaffold with the repository pattern
  6. 02 · OAuth2 password flow with JWT
  7. 03 · Pydantic v2 request and response models
  8. 04 · Async SQLAlchemy session dependency
  9. 05 · BackgroundTasks for fire-and-forget work
  10. 06 · Global exception handlers
  11. 07 · pytest with httpx.AsyncClient
  12. 08 · Pagination and filtering on list endpoints
  13. 09 · Dockerfile with uvicorn and gunicorn
  14. 10 · API-key middleware on top of OpenAPI
  15. Community signal
  16. The contrarian take
  17. Real APIs shipped
  18. Gotchas
  19. Pairs well with
  20. FAQ
  21. Sources

What this skill actually does

Sixty seconds of context before the cookbook — what the fastapi skill is, what Claude returns when you trigger it, and the one thing it does NOT do for you.

What this skill actually does

Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling.

wshobson, the skill author · /skills/fastapi-templates

What Claude returns

When triggered, Claude scaffolds a layered FastAPI project — api/, core/, models/, schemas/, services/, repositories/ — instead of one fat main.py. It returns SQLAlchemy 2.0 async models, Pydantic v2 schemas, a generic async `BaseRepository`, a service layer, endpoints wired through `Depends(get_db)`, and a `core/security.py` with python-jose JWT plus passlib bcrypt. Tests come as a `conftest.py` using an in-memory SQLite database and `httpx.AsyncClient`.

What it does NOT do

It does not install FastAPI, uvicorn, or your database driver — you still `pip install` the dependencies and run the migrations yourself.

How you trigger it

Scaffold a new FastAPI service with auth and tests.Set up an async FastAPI project with a Postgres repository layer.Add OAuth2 JWT login to my FastAPI app.

Cost when idle

~100 tokens at idle (the skill name + description in the system prompt). The body and references/details.md load only when triggered.

The cookbook

Each entry below is a piece of a FastAPI service you could ship this week. They run roughly in build order — the early ones lay down the structure (repository, schemas, session), the middle ones add the cross-cutting concerns (auth, background work, error handling), and the later ones get the thing deployed (tests, pagination, Docker, an API key). Every entry pairs with one or two skills or MCP servers already on mcp.directory.

One framing note worth stating up front. FastAPI is, by the maintainer’s own framing, “high performance, easy to learn, fast to code, ready for production” — and it is one of the most-starred Python web frameworks on GitHub, approaching six figures. The skill’s value isn’t teaching you FastAPI; it’s skipping the hour you’d spend re-deciding the same project layout every time you start a service.

Install + README

If the skill isn’t on your machine yet, here’s the one-liner. The full install panel (Codex, Copilot, Antigravity variants) is on the skill page — the same UI’s embedded below.

One-line install · by wshobson

Open skill page

Install

mkdir -p .claude/skills/fastapi-templates && curl -L -o skill.zip "https://mcp.directory/api/skills/download/132" && unzip -o skill.zip -d .claude/skills/fastapi-templates && rm skill.zip

Installs to .claude/skills/fastapi-templates

Watch it built

The most-watched FastAPI course on YouTube. It builds the exact stack the skill scaffolds — Pydantic schemas, SQLAlchemy models, OAuth2 plus JWT auth, and pytest — so it’s the fastest way to recognize the code the cookbook prompts produce before you read them.

01

Async CRUD scaffold with the repository pattern

A users resource wired end to end: a generic async repository, a thin endpoint layer, and a `get_db` session dependency. The skill's house layout is api/core/models/schemas/services/repositories, so the scaffold drops in without re-architecting later.

ForAnyone starting a fresh FastAPI service who wants structure on day one.

The prompt

Scaffold a `users` resource using the fastapi-templates skill's layered layout (api/, core/, models/, schemas/, services/, repositories/). Generate `repositories/base_repository.py` as a generic async `BaseRepository[ModelType, CreateSchemaType, UpdateSchemaType]` with `get`, `get_multi(skip, limit)`, `create`, `update(exclude_unset)`, and `delete`. Use SQLAlchemy 2.0 `select()` + `await db.execute(...)`, never the legacy `db.query()`. Then a `UserRepository(BaseRepository)` subclass with `get_by_email`. Wire the endpoints in `api/v1/endpoints/users.py` through `Depends(get_db)`.

What slides.md looks like

# repositories/base_repository.py
from typing import Generic, TypeVar, Type, Optional, List
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from pydantic import BaseModel

ModelType = TypeVar("ModelType")
CreateSchemaType = TypeVar("CreateSchemaType", bound=BaseModel)

class BaseRepository(Generic[ModelType, CreateSchemaType]):
    def __init__(self, model: Type[ModelType]):
        self.model = model

    async def get(self, db: AsyncSession, id: int) -> Optional[ModelType]:
        result = await db.execute(select(self.model).where(self.model.id == id))
        return result.scalars().first()

    async def get_multi(self, db: AsyncSession, skip: int = 0, limit: int = 100):
        result = await db.execute(select(self.model).offset(skip).limit(limit))
        return result.scalars().all()

One-line tweak

Ask for the same scaffold against MongoDB instead of SQLAlchemy — the skill swaps the repository internals for Motor while keeping the endpoint and service signatures identical.

02

OAuth2 password flow with JWT

A `/auth/login` endpoint that takes form credentials, verifies the bcrypt hash, and returns a signed JWT. The skill ships `create_access_token`, `verify_password`, and `get_password_hash` in `core/security.py` using python-jose and passlib — the exact stack FastAPI's own security docs use.

ForBackend devs adding token auth to an API without reaching for a SaaS.

The prompt

Add OAuth2 password-flow auth following the fastapi-templates security pattern. In `core/security.py`: `pwd_context = CryptContext(schemes=['bcrypt'])`, `create_access_token(data, expires_delta)` signing with `settings.SECRET_KEY` and HS256, plus `verify_password` and `get_password_hash`. In `api/dependencies.py`: `oauth2_scheme = OAuth2PasswordBearer(tokenUrl='/api/v1/auth/login')` and a `get_current_user` dependency that decodes the token, reads `sub`, and loads the user from the repository — raising a 401 with a `WWW-Authenticate: Bearer` header on any JWTError.

What slides.md looks like

# core/security.py
from datetime import datetime, timedelta
from jose import jwt
from passlib.context import CryptContext
from app.core.config import get_settings

settings = get_settings()
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
ALGORITHM = "HS256"

def create_access_token(data: dict, expires_delta: timedelta | None = None):
    to_encode = data.copy()
    expire = datetime.utcnow() + (expires_delta or timedelta(minutes=15))
    to_encode.update({"exp": expire})
    return jwt.encode(to_encode, settings.SECRET_KEY, algorithm=ALGORITHM)

def verify_password(plain: str, hashed: str) -> bool:
    return pwd_context.verify(plain, hashed)

One-line tweak

Ask for refresh-token rotation on top — the skill adds a second short-lived/long-lived token pair and a `/auth/refresh` endpoint without touching the login route.

03

Pydantic v2 request and response models

A schemas module with separate `UserBase`, `UserCreate`, `UserUpdate`, and `User` (read) models so the password never leaks into a response. The skill uses Pydantic v2 conventions — `model_config = ConfigDict(from_attributes=True)` to read straight off ORM rows.

ForDevelopers who keep accidentally returning the password hash in API responses.

The prompt

Generate `schemas/user.py` with Pydantic v2 models: `UserBase` (email: EmailStr, name: str), `UserCreate(UserBase)` adding `password: str` with `Field(min_length=8)`, `UserUpdate` with every field `Optional` for PATCH, and a read `User(UserBase)` that adds `id: int` and `is_active: bool` and sets `model_config = ConfigDict(from_attributes=True)`. The read model must never include the password. Use `field_validator` to lowercase the email on input.

What slides.md looks like

# schemas/user.py
from pydantic import BaseModel, EmailStr, Field, ConfigDict, field_validator

class UserBase(BaseModel):
    email: EmailStr
    name: str

    @field_validator("email")
    @classmethod
    def lower_email(cls, v: str) -> str:
        return v.lower()

class UserCreate(UserBase):
    password: str = Field(min_length=8)

class User(UserBase):
    id: int
    is_active: bool
    model_config = ConfigDict(from_attributes=True)

One-line tweak

Swap `from_attributes=True` validation onto a nested `items: list[Item]` field and the same model serializes a user with their related rows in one response.

04

Async SQLAlchemy session dependency

The `get_db` dependency that every endpoint leans on: an async session factory that commits on success, rolls back on any exception, and always closes. This is the single most copy-pasted piece of a FastAPI codebase, and the skill gets the commit/rollback boundary right.

ForTeams whose endpoints leak sessions or forget to roll back on error.

The prompt

Generate `core/database.py` per the fastapi-templates pattern: `create_async_engine(settings.DATABASE_URL, future=True)`, an `AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)`, a `Base = declarative_base()`, and a `get_db()` async generator dependency that yields a session, commits on success, rolls back inside an `except` block, and closes in `finally`. Show how an endpoint consumes it with `db: AsyncSession = Depends(get_db)`.

What slides.md looks like

# core/database.py
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker, declarative_base
from app.core.config import get_settings

settings = get_settings()
engine = create_async_engine(settings.DATABASE_URL, echo=True, future=True)
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
Base = declarative_base()

async def get_db():
    async with AsyncSessionLocal() as session:
        try:
            yield session
            await session.commit()
        except Exception:
            await session.rollback()
            raise
        finally:
            await session.close()

One-line tweak

Point `DATABASE_URL` at `sqlite+aiosqlite:///:memory:` and the exact same dependency powers your test suite — no second session factory to maintain.

05

BackgroundTasks for fire-and-forget work

An endpoint that returns 202 immediately and runs the slow part — a welcome email, a webhook, a cache warm — after the response is sent, using FastAPI's built-in `BackgroundTasks`. No Celery, no broker, for work that fits inside the process.

ForDevelopers who reach for Celery when a background task would do.

The prompt

Add a `POST /api/v1/users/` flow that creates the user, then schedules a welcome email via FastAPI `BackgroundTasks` so the request returns 201 without waiting on SMTP. Show the `background_tasks: BackgroundTasks` parameter and `background_tasks.add_task(send_welcome_email, user.email)`. Make `send_welcome_email` an async function. Add a one-line note on when this is the wrong tool — i.e. when the work must survive a process restart, reach for a real queue.

What slides.md looks like

# api/v1/endpoints/users.py
from fastapi import APIRouter, BackgroundTasks, Depends, status
from app.services.email_service import send_welcome_email

router = APIRouter()

@router.post("/", response_model=User, status_code=status.HTTP_201_CREATED)
async def create_user(
    user_in: UserCreate,
    background_tasks: BackgroundTasks,
    db: AsyncSession = Depends(get_db),
):
    user = await user_service.create_user(db, user_in)
    background_tasks.add_task(send_welcome_email, user.email)
    return user

One-line tweak

Swap the email task for an outbound webhook `httpx.AsyncClient().post(...)` and the same endpoint notifies a downstream service after responding.

06

Global exception handlers

One place that turns domain errors into clean JSON instead of leaking stack traces. The skill maps a service-layer `ValueError` ("Email already registered") to a 400, validation errors to 422, and anything unhandled to a logged 500 — so endpoints stay thin.

ForAnyone tired of `try/except HTTPException` boilerplate in every route.

The prompt

Register global exception handlers on the app. Add `@app.exception_handler(ValueError)` returning a 400 JSONResponse with `{'detail': str(exc)}`, override the default `RequestValidationError` handler to log and return 422, and a catch-all `Exception` handler that logs the traceback and returns a generic 500 without leaking internals. Keep the service layer raising plain `ValueError` / domain exceptions so endpoints don't each wrap their own try/except.

What slides.md looks like

# core/handlers.py
import logging
from fastapi import Request, status
from fastapi.responses import JSONResponse

logger = logging.getLogger(__name__)

def register_handlers(app):
    @app.exception_handler(ValueError)
    async def value_error_handler(request: Request, exc: ValueError):
        return JSONResponse(status_code=400, content={"detail": str(exc)})

    @app.exception_handler(Exception)
    async def unhandled_handler(request: Request, exc: Exception):
        logger.exception("Unhandled error on %s", request.url.path)
        return JSONResponse(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            content={"detail": "Internal server error"},
        )

One-line tweak

Add a custom `EntityNotFound` exception and map it to 404 in the same module — now repositories can raise it instead of returning `None` and you delete the per-route 404 checks.

07

pytest with httpx.AsyncClient

A real async test suite: an in-memory SQLite database per test, the `get_db` dependency overridden, and requests fired through `httpx.AsyncClient` against the app. The skill ships the `conftest.py` fixtures verbatim — `db_session`, `client`, and the `dependency_overrides` wiring.

ForDevelopers who want endpoint tests that touch the real request path, not mocks.

The prompt

Generate the fastapi-templates testing setup: a `conftest.py` with an async `db_session` fixture using `sqlite+aiosqlite:///:memory:`, a `client` fixture that overrides `app.dependency_overrides[get_db]` to yield the test session and wraps the app in `httpx.AsyncClient(app=app, base_url='http://test')`, and a `test_users.py` that `await client.post('/api/v1/users/', json={...})` and asserts the 201 response shape. Mark async tests with `@pytest.mark.asyncio`.

What slides.md looks like

# tests/conftest.py
import pytest
from httpx import AsyncClient
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
from app.main import app
from app.core.database import get_db, Base

TEST_DATABASE_URL = "sqlite+aiosqlite:///:memory:"

@pytest.fixture
async def client(db_session):
    async def override_get_db():
        yield db_session
    app.dependency_overrides[get_db] = override_get_db
    async with AsyncClient(app=app, base_url="http://test") as c:
        yield c

One-line tweak

Parametrize `test_create_user` with `@pytest.mark.parametrize` over a table of bad payloads to assert every 422 validation path in one test function.

08

Pagination and filtering on list endpoints

A `GET /items` that takes `skip`, `limit`, and a couple of filters as typed query parameters and returns a paginated payload. The skill builds on the repository's `get_multi(skip, limit)` and adds `Query(...)` validation so a caller can't request 10,000 rows.

ForTeams whose list endpoints return the entire table by default.

The prompt

Add pagination and filtering to `GET /api/v1/items/`. Accept `skip: int = Query(0, ge=0)`, `limit: int = Query(20, ge=1, le=100)`, and optional `status: str | None = Query(None)`. Extend the repository with a `get_filtered(db, skip, limit, status)` that conditionally adds `.where(Item.status == status)` to the `select()`. Return a `{'items': [...], 'total': int, 'skip': skip, 'limit': limit}` envelope so the client can render pagination.

What slides.md looks like

# api/v1/endpoints/items.py
from fastapi import APIRouter, Depends, Query
from sqlalchemy import select, func

@router.get("/")
async def list_items(
    skip: int = Query(0, ge=0),
    limit: int = Query(20, ge=1, le=100),
    status: str | None = Query(None),
    db: AsyncSession = Depends(get_db),
):
    stmt = select(Item)
    if status:
        stmt = stmt.where(Item.status == status)
    total = await db.scalar(select(func.count()).select_from(stmt.subquery()))
    rows = (await db.execute(stmt.offset(skip).limit(limit))).scalars().all()
    return {"items": rows, "total": total, "skip": skip, "limit": limit}

One-line tweak

Add `order_by: str = Query('id')` and map it to a column allowlist so callers can sort without exposing arbitrary SQL ordering.

09

Dockerfile with uvicorn and gunicorn

A multi-stage Dockerfile that builds dependencies, copies the app, and runs gunicorn with uvicorn workers for production — the pattern the FastAPI deployment docs recommend over a bare `uvicorn` for multi-core hosts.

ForDevelopers shipping a FastAPI service to a container platform.

The prompt

Write a production `Dockerfile` for the fastapi-templates project. Use a `python:3.12-slim` base, install dependencies from `requirements.txt` in a cached layer before copying source, run as a non-root user, expose 8000, and start with `gunicorn app.main:app -k uvicorn.workers.UvicornWorker -w 4 --bind 0.0.0.0:8000`. Add a `.dockerignore` and a `HEALTHCHECK` that curls `/health`. Explain in one line why gunicorn-with-uvicorn-workers beats a single uvicorn process for production.

What slides.md looks like

# Dockerfile
FROM python:3.12-slim
WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .
RUN useradd -m appuser && chown -R appuser /app
USER appuser

EXPOSE 8000
HEALTHCHECK --interval=30s CMD curl -f http://localhost:8000/health || exit 1
CMD ["gunicorn", "app.main:app", "-k", "uvicorn.workers.UvicornWorker", \
     "-w", "4", "--bind", "0.0.0.0:8000"]

One-line tweak

Drop the worker count and switch the CMD to plain `uvicorn ... --reload` behind a build arg so the same Dockerfile serves local development.

10

API-key middleware on top of OpenAPI

Custom middleware that checks an `X-API-Key` header on machine-to-machine routes while leaving the interactive OpenAPI docs reachable. The skill registers it as ASGI middleware and excludes `/docs`, `/openapi.json`, and `/health` so you don't lock yourself out.

ForTeams exposing an internal API to other services, not human users.

The prompt

Add API-key middleware to the FastAPI app. Register a `@app.middleware('http')` function that reads `X-API-Key`, compares it against `settings.API_KEYS` (a set), and returns a 401 JSONResponse for protected paths — but skips the check for `/docs`, `/redoc`, `/openapi.json`, and `/health` so the interactive docs stay open. Keep FastAPI's auto-generated OpenAPI schema intact, and document the header with an `APIKeyHeader` security scheme so it shows up in /docs.

What slides.md looks like

# core/middleware.py
from fastapi import Request, status
from fastapi.responses import JSONResponse

OPEN_PATHS = {"/docs", "/redoc", "/openapi.json", "/health"}

def add_api_key_middleware(app, settings):
    @app.middleware("http")
    async def api_key_guard(request: Request, call_next):
        if request.url.path in OPEN_PATHS:
            return await call_next(request)
        if request.headers.get("X-API-Key") not in settings.API_KEYS:
            return JSONResponse(status_code=401, content={"detail": "Invalid API key"})
        return await call_next(request)

One-line tweak

Move the key set into a database table and look it up per request to support per-client key rotation and revocation without a redeploy.

Community signal

Three voices on running FastAPI in real production. The first is the strongest name-brand endorsement — a Microsoft engineer — the second is the honest daily-use story with its one caveat, the third is a regulated-industry deployment.

I'm using FastAPI a ton these days. I'm actually planning to use it for all of my team's ML services at Microsoft. Some of them are getting integrated into the core Windows product and some Office products.

Kabir Khan (Microsoft) · Blog

Named testimonial on the official FastAPI site — a Microsoft engineer adopting it for the team's ML services.

Source
We're using FastAPI in production at InvestSuite. Highly productive framework, very well written documentation. You get jump started right away. Only caveat with async python. Might be tricky when using 'sync' libraries.

lukin0110 · Hacker News

Hacker News comment from an engineer running FastAPI in production at a fintech, naming the one real footgun: sync libraries inside async routes.

Source
I absolutely recommend FastAPI for production environments. I built a HIPAA compliant Medicare self-enrollment platform backed by FastAPI. It's based on veteran Starlette - ASGI framework

u/dastardly_uno · Reddit

Reply in an r/FastAPI 'is it production-ready?' thread describing a regulated healthcare deployment built on FastAPI.

Source

The contrarian take

FastAPI isn’t free of sharp edges, and the most useful critiques are about performance, not popularity. Here’s a concrete one from m_ke on Hacker News:

I also ran into some really bad validation / serialization performance degradations for large response bodies. Serializing responses with a few 100 small objects or neural network embeddings would take a function that takes 7ms and blow it up to 100-200ms.

m_ke · Hacker News

Hacker News thread on FastAPI in production — a real serialization cost from the Pydantic v1 era.

Source

This was a real Pydantic v1 cost. Pydantic v2 — the default since FastAPI 0.100 in mid-2023 — rewrote validation and serialization in Rust and largely closes the gap, and the skill's models are v2. On a genuinely hot path you can still return a pre-serialized `Response` to skip model serialization entirely.

The other recurring critique is scope: FastAPI is a framework for APIs, not a batteries-included monolith. There’s no built-in ORM, admin, or migration tool the way Django ships them. The skill answers half of that by giving you an opinionated SQLAlchemy + Alembic-ready structure out of the gate — but if you want an admin panel and a CMS, FastAPI is the wrong starting point and no skill changes that.

Real APIs shipped with FastAPI

Concrete examples from public projects and companies. Most don’t use the Claude skill specifically — they’re here to show what production FastAPI looks like, so you have a target shape in mind when you write the prompt.

Gotchas (the four that bite)

Sourced from the FastAPI concurrency docs and the skill’s own fastapi-templates source.

Sync calls inside async routes block the event loop

The most cited FastAPI footgun. Call a synchronous DB driver or `requests.get()` inside an `async def` route and you stall every other request on that worker. The skill defaults to async drivers (asyncpg, aiosqlite) and the async SQLAlchemy API for exactly this reason. If you must call sync code, push it to a thread with `run_in_threadpool` or define the route as plain `def` so FastAPI runs it in the threadpool itself.

Pydantic v1 examples don't match v2 output

Half the FastAPI tutorials online still show `orm_mode = True` and `@validator`. The skill writes Pydantic v2 (`model_config = ConfigDict(from_attributes=True)`, `field_validator`). Mixing the two raises deprecation warnings and, occasionally, silent behavior changes. Pick one — and the skill picked v2.

The session dependency must commit AND roll back

A `get_db` that yields a session but never rolls back on exception leaves a half-applied transaction and a connection in a bad state. The skill's dependency commits on success, rolls back inside `except`, and closes in `finally`. If you hand-roll your own, copy that exact shape (use case 4).

Background tasks die with the process

FastAPI's `BackgroundTasks` run in the same process after the response. If the worker restarts or crashes mid-task, that work is gone — there's no retry, no durability. Great for a welcome email, wrong for anything that must not be lost. The skill uses BackgroundTasks for fire-and-forget and tells you to reach for a real queue when durability matters.

Pairs well with

Curated to match the cookbook’s actual integrations: the backend-adjacent skills (backend-architect, jwt-auth, security-auditor, test-automator) plus the database and deploy MCP servers the use cases lean on.

Two posts that compose well with this cookbook: What are Claude Code skills? covers the underlying mechanism, and What is MCP? explains the protocol behind the MCP servers you’d pair with a FastAPI backend — the natural next step once the API exists and you want an AI client to call it.

Frequently asked questions

Do I need to know FastAPI before using the fastapi skill?

No, but it helps you review the output. The fastapi skill writes the project structure, async session handling, and auth wiring for you. You still need Python and a `pip install` of FastAPI, uvicorn, SQLAlchemy, python-jose, and passlib. Reading the generated code is the fastest way to learn the layered pattern — every cookbook entry above shows the shape it produces.

Is there a FastAPI MCP server I should use instead of the fastapi skill?

They solve different problems. The fastapi-templates skill writes your application code at authoring time. There are MCP servers that turn an existing FastAPI app into a live tool surface (the fastapi-mcp project exposes your routes as MCP tools). They're complementary: use the skill to scaffold the API, then bolt an MCP server on top if you want an AI client to call your endpoints at runtime. For just building the backend, the skill is the lighter choice — about 100 idle tokens versus an MCP whose tool schemas load every turn.

Does the fastapi skill use SQLAlchemy 2.0 async or the old query API?

Async 2.0. The skill's repository pattern uses `select()` statements with `await db.execute(...)` and `result.scalars().first()`, not the legacy `db.query(...)` style. The session dependency is built on `create_async_engine` and `AsyncSession`. That matters because the legacy query API blocks the event loop, which is the single most common way a FastAPI app loses the performance it was chosen for.

Can the fastapi skill set up JWT authentication?

Yes — use case 2 above is exactly that. The skill ships `core/security.py` with `create_access_token`, `verify_password`, and `get_password_hash` using python-jose and passlib's bcrypt context, plus an `OAuth2PasswordBearer` scheme and a `get_current_user` dependency. It's the same OAuth2 password flow FastAPI's own security tutorial documents, so the generated code matches the canonical reference.

Does the skill handle Pydantic v2 or v1?

Pydantic v2. The generated schemas use v2 conventions like `model_config = ConfigDict(from_attributes=True)` and `field_validator`. That's worth checking because a lot of older FastAPI tutorials still show v1 `orm_mode` and `@validator`, which raise deprecation warnings on modern FastAPI. If you paste v1 examples next to the skill's output, expect friction.

What's the difference between the fastapi skill and pasting a FastAPI template into CLAUDE.md?

A skill loads only when you trigger it, so it costs roughly 100 tokens at idle. A CLAUDE.md loads on every turn — you'd pay the FastAPI boilerplate tax even while editing unrelated code. Use the skill if you scaffold APIs occasionally; a CLAUDE.md only earns its keep if every session in the project touches the backend.

Why does 'fastapi' get impressions on Google but few clicks?

The bare 'fastapi' query returns the official docs at fastapi.tiangolo.com and the GitHub repo as the top results — no third-party page outranks them, and it shouldn't. This post targets the long-tail intent instead: 'fastapi skill', 'fastapi skills', 'claude fastapi skill', and 'fastapi agent skill'. Those are the queries where a cookbook of real prompts is the thing the searcher actually wants.

Sources

Primary

Community

Critical and contrarian

Internal

Keep reading