fastapi
Skill0 starsChanged 3 months agoMITView on GitHub
Build production-ready Python APIs with FastAPI using type hints, async/await, dependency injection, and automatic OpenAPI documentation
- Installs packages
27 other projects use a version of this.
Adopted by
Most recently taken up by
- gurupak/claude-skillstheir own version, first seen Oct 25, 2026
- DongDuong2001/pudo-code-systemtheir own version, first seen Oct 13, 2026
- G1Joshi/Agent-Skillstheir own version, first seen Oct 13, 2026
- nimadorostkar/Claude-Skills-collectiontheir own version, first seen Oct 13, 2026
- qyndex/claude-inittheir own version, first seen Oct 13, 2026
- kid-sid/claude-spellbooktheir own version, first seen Oct 9, 2026
Used with
Projects with it also use react, python and 2 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
VercelSkillreact
React renderer for json-render that turns JSON specs into React components. Use when working with @json-render/react, building React UIs from JSON, creating component catalogs, or rendering AI-generated specs.
Also in 3 projects that use this
rogue-dev-studioSkillpython
Python 3.13 with uv package manager via mise. Use when the project needs this capability or the user / team manifest asks for it. Use for specialized `python` work when listed in TEAM.yaml or explicitly requested.
Also in 3 projects that use this
BlockSkillplan
Draft a TDD, PRD, or lightweight plan in the conversation without committing it.
Also in 3 projects that use this
BlockSkillfrontend-design
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
Also in 3 projects that use this
Other versions27 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 27
- kid-sid/claude-spellbook★ 190same name
- youlaitech/youlai-skills★ 63same name
- Bbar0n234/learnflow-ai★ 35same name
- nimadorostkar/Claude-Skills-collection★ 33same name
- G1Joshi/Agent-Skills★ 15same name
- harness-studio/harness-studio★ 9same name
- DongDuong2001/pudo-code-system★ 5same name
- jawwad-ali/claude-code-skills★ 4same name
- Spardutti/claude-skills★ 3same name
- ffsshhttiikk/opencode-agents-skills★ 2same name
17 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository27 other files it gives its agents.
- architecture-designerSkill
- architecture-patternsSkill
- code-reviewSkill
- dockerSkill
- feature-specificationSkill
- github-issue-resolverSkill
- github-opsSkill
- kubernetes-devopsSkill
- monitoringSkill
- nextjsSkill
- nginxSkill
- prd-to-ddd-designSkill
- prd-writerSkill
- prismaSkill
- react-expertSkill
- redisSkill
- redis-storeSkill
- requirements-analysisSkill
- shadcn-uiSkill
- ssh-essentialsSkill
- task-decomposerSkill
- task-development-workflowSkill
- trpc-best-practicesSkill
- typescript-proSkill
- typescriptSkill
- webhookSkill
- zodSkill
The file
We split this skill into the rules it gives an agent
8 rules. 0 are common, 5 are distinctive, and 3 are very specific to this project.
0
Common
Most of the 25 edited versions we read keep these.
5
Distinctive
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 26
Use this skill when:
- Distinctive: line 36
Don't use: when you need:
- Very specific: line 84
Karpathy Principle: Simplicity First: - Start with a single main.py file.
- Distinctive: line 86
Karpathy Principle: When NOT to Use: - Don't use FastAPI for CPU-intensive batch jobs (use Celery).
- Very specific: line 184
Karpathy Principle: Goal-Driven Execution: - After setting up dependencies, test them in isolation: curl http://localhost:8000/me should …
- Very specific: line 186
Karpathy Principle: Security By Design: - Default Pydantic validation stops 80% of attacks.
- Distinctive: line 369
Karpathy Principle: Surgical Changes: - Add middleware (CORS, auth, logging) one at a time.
- Distinctive: line 473
Before deploying FastAPI applications:
“Common” is measured: kept by at least 6 in 10 of the 25 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
FastAPI - Modern Python API Framework
When to Use
Use this skill when:
- Building REST APIs in Python with automatic validation
- Need async/await support for high concurrency
- Want automatic OpenAPI (Swagger) documentation
- Type safety and editor autocompletion matter
- Rapid prototyping with production-quality code
- Integrating with modern Python tools (Pydantic, SQLAlchemy 2.0)
- WebSocket or Server-Sent Events (SSE) support needed
Don't use when you need:
- Long-established ecosystem (Flask/Django have more libraries)
- Template rendering as primary feature (use Django)
- Python 2.7 support (FastAPI requires Python 3.7+)
- Zero learning curve (FastAPI concepts require understanding async/type hints)
Karpathy Principle: Think Before Coding - FastAPI's async support is powerful but easy to misuse. If you mix sync database drivers in async endpoints, you'll block the entire event loop. Plan your architecture before writing code.
Karpathy Principle: Trade-offs Everywhere - FastAPI's async runtime means: use async def for I/O-bound (DB, API calls), use def for CPU-bound (image processing). Mixing them wrong blocks the event loop.
Prerequisites
Required Knowledge
- Python 3.9+ (type hints, async/await)
- REST API concepts (HTTP methods, status codes, headers)
- Pydantic basics (validation, models)
- Async programming fundamentals
Required Tools
# Install FastAPI
pip install fastapi[all] # Includes uvicorn, pydantic, etc.
# Or minimal install
pip install fastapi uvicorn[standard] pydantic
# For async database
pip install sqlalchemy[asyncio] asyncpg # PostgreSQL
pip install sqlalchemy[asyncio] aiomysql # MySQL
# Development tools
pip install pytest httpx pytest-asyncioProject Structure
app/
├── main.py # FastAPI app
├── models.py # Pydantic models
├── database.py # Database setup
├── routers/
│ ├── __init__.py
│ ├── users.py
│ └── posts.py
├── dependencies.py # Shared dependencies
└── config.py # SettingsKarpathy Principle: Simplicity First - Start with a single main.py file. Split into routers and modules only when you have 10+ endpoints. Premature organization adds complexity.
Karpathy Principle: When NOT to Use - Don't use FastAPI for CPU-intensive batch jobs (use Celery). Don't use it for WebSockets at scale (use dedicated WS server). Async doesn't fix CPU bottlenecks.
Core Workflows
1. Basic Application Setup
Simple API:
# main.py
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI(title="My API", version="1.0.0")
class Item(BaseModel):
name: str
price: float
is_available: bool = True
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
@app.post("/items", status_code=201)
async def create_item(item: Item):
return item
# Run with: uvicorn main:app --reloadWith Lifespan (startup/shutdown):
from contextlib import asynccontextmanager
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
@asynccontextmanager
async def lifespan(app: FastAPI):
# Startup
app.state.db_engine = create_async_engine("postgresql+asyncpg://...")
yield
# Shutdown
await app.state.db_engine.dispose()
app = FastAPI(lifespan=lifespan)2. Dependency Injection
Database Dependency:
# database.py
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker
engine = create_async_engine("postgresql+asyncpg://user:pass@localhost/db")
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
async def get_db():
async with AsyncSessionLocal() as session:
yield session
# Usage in endpoint
from fastapi import Depends
from sqlalchemy.ext.asyncio import AsyncSession
@app.get("/users/{user_id}")
async def read_user(user_id: int, db: AsyncSession = Depends(get_db)):
result = await db.execute(select(User).where(User.id == user_id))
user = result.scalar_one_or_none()
if not user:
raise HTTPException(status_code=404, detail="User not found")
return userAuthentication Dependency:
from fastapi import Depends, HTTPException
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
security = HTTPBearer()
async def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)):
token = credentials.credentials
# Verify token (JWT, etc.)
user = await verify_token(token)
if not user:
raise HTTPException(status_code=401, detail="Invalid token")
return user
@app.get("/me")
async def read_current_user(user = Depends(get_current_user)):
return userKarpathy Principle: Goal-Driven Execution - After setting up dependencies, test them in isolation: curl http://localhost:8000/me should return 401 without a token, not 500. Verify error handling works before building on it.
Karpathy Principle: Security By Design - Default Pydantic validation stops 80% of attacks. But enable CORS carefully (allow_origins=["*"] = security disaster). Validate file uploads (size, type, content).
3. Request Validation with Pydantic
Input Validation:
from pydantic import BaseModel, Field, EmailStr, validator
from typing import Annotated
class UserCreate(BaseModel):
email: EmailStr
password: Annotated[str, Field(min_length=8)]
age: Annotated[int, Field(ge=18, le=120)]
@validator('password')
def password_strength(cls, v):
if not any(c.isupper() for c in v):
raise ValueError('Password must contain uppercase letter')
return v
@app.post("/users")
async def create_user(user: UserCreate):
# user is validated automatically
return {"email": user.email, "age": user.age}Query Parameters with Validation:
from typing import Annotated
from fastapi import Query
@app.get("/items")
async def list_items(
skip: Annotated[int, Query(ge=0)] = 0,
limit: Annotated[int, Query(ge=1, le=100)] = 10,
search: Annotated[str | None, Query(max_length=50)] = None,
):
return {"skip": skip, "limit": limit, "search": search}4. Error Handling
Custom Exceptions:
from fastapi import HTTPException, Request
from fastapi.responses import JSONResponse
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: Request, exc: ItemNotFoundError):
return JSONResponse(
status_code=404,
content={"detail": f"Item {exc.item_id} not found"},
)
@app.get("/items/{item_id}")
async def read_item(item_id: int):
item = await db.get(item_id)
if not item:
raise ItemNotFoundError(item_id)
return itemValidation Error Handling:
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
return JSONResponse(
status_code=422,
content={"detail": exc.errors(), "body": exc.body},
)Common Patterns
1. Pagination
from typing import TypeVar, Generic
from pydantic import BaseModel
T = TypeVar('T')
class Page(BaseModel, Generic[T]):
items: list[T]
total: int
page: int
size: int
pages: int
async def paginate(query, page: int, size: int):
total = await db.execute(select(func.count()).select_from(query.subquery()))
total = total.scalar()
items = await db.execute(query.offset((page - 1) * size).limit(size))
items = items.scalars().all()
return Page(
items=items,
total=total,
page=page,
size=size,
pages=(total + size - 1) // size,
)
@app.get("/users", response_model=Page[UserOut])
async def list_users(page: int = 1, size: int = 10, db: AsyncSession = Depends(get_db)):
query = select(User).order_by(User.created_at.desc())
return await paginate(query, page, size)2. Background Tasks
from fastapi import BackgroundTasks
def send_email(email: str, subject: str, body: str):
# Send email (runs after response)
pass
@app.post("/users")
async def create_user(user: UserCreate, background_tasks: BackgroundTasks):
# Create user in DB
new_user = await db.create(user)
# Send welcome email in background
background_tasks.add_task(send_email, user.email, "Welcome!", "Thanks for joining")
return new_user3. File Upload
from fastapi import UploadFile, File
@app.post("/upload")
async def upload_file(file: UploadFile = File(...)):
content = await file.read()
# Process file
return {"filename": file.filename, "size": len(content)}
@app.post("/upload-multiple")
async def upload_multiple(files: list[UploadFile] = File(...)):
return [{"filename": f.filename} for f in files]4. WebSocket
from fastapi import WebSocket, WebSocketDisconnect
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
try:
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Echo: {data}")
except WebSocketDisconnect:
print("Client disconnected")5. CORS
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"], # Frontend URL
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)Karpathy Principle: Surgical Changes - Add middleware (CORS, auth, logging) one at a time. Test after each addition. Middleware order matters - CORS must come before exception handlers or errors won't have CORS headers.
Karpathy Principle: Own Your Dependencies - Pin versions in requirements.txt. Starlette/Pydantic major upgrades break APIs. Use pip freeze > requirements.txt after testing.
Common Pitfalls
1. Mixing Sync/Async
❌ Bad (blocks event loop):
@app.get("/users")
async def get_users(db: Session = Depends(get_db)): # Sync Session!
users = db.query(User).all() # Blocks!
return users✅ Good (fully async):
@app.get("/users")
async def get_users(db: AsyncSession = Depends(get_db)):
result = await db.execute(select(User))
users = result.scalars().all()
return users2. Mutable Default Arguments
❌ Bad (shared state):
class Item(BaseModel):
tags: list[str] = [] # Same list for all instances!✅ Good (factory):
from pydantic import Field
class Item(BaseModel):
tags: list[str] = Field(default_factory=list)3. Missing Status Codes
❌ Bad (returns 200 for creation):
@app.post("/users")
async def create_user(user: UserCreate):
return await db.create(user)✅ Good (returns 201):
@app.post("/users", status_code=201)
async def create_user(user: UserCreate):
return await db.create(user)4. No Error Handling
❌ Bad (500 for not found):
@app.get("/users/{user_id}")
async def get_user(user_id: int, db: AsyncSession = Depends(get_db)):
result = await db.execute(select(User).where(User.id == user_id))
return result.scalar_one() # Raises if not found!✅ Good (404 for not found):
@app.get("/users/{user_id}")
async def get_user(user_id: int, db: AsyncSession = Depends(get_db)):
result = await db.execute(select(User).where(User.id == user_id))
user = result.scalar_one_or_none()
if not user:
raise HTTPException(status_code=404, detail="User not found")
return user5. Blocking CPU Work in Async
❌ Bad (blocks event loop):
@app.post("/process")
async def process_data(data: dict):
result = expensive_computation(data) # Blocks!
return result✅ Good (offload to executor):
import asyncio
from concurrent.futures import ProcessPoolExecutor
executor = ProcessPoolExecutor()
@app.post("/process")
async def process_data(data: dict):
loop = asyncio.get_event_loop()
result = await loop.run_in_executor(executor, expensive_computation, data)
return resultVerification Checklist
Before deploying FastAPI applications:
Code Quality
- All endpoints use async/await correctly
- Database drivers are async (asyncpg, aiomysql)
- No blocking operations in async endpoints
- Pydantic models use
Field(default_factory=...)for mutable defaults - Type hints on all function parameters
API Design
- POST endpoints return 201 status code
- Error responses use HTTPException
- Pagination on list endpoints
- Validation on all inputs
- Consistent response formats
Security
- Authentication on protected endpoints
- CORS configured (if needed)
- No sensitive data in logs
- Rate limiting (if public API)
- Input validation on all user data
Performance
- Database queries are async
- Connection pooling configured
- CPU-bound work offloaded to executors
- File uploads limited in size
- Background tasks for slow operations
Integration with Other Skills
With PostgreSQL / Prisma
- SQLAlchemy 2.0 with async support
- Alembic for migrations
- Connection pooling
With Redis
- Async Redis client (redis-py with asyncio)
- Caching with
@lru_cacheor Redis - Session storage
With Docker
- Multi-stage build for smaller images
- Health check endpoint
- uvicorn with workers
With Next.js / React
- CORS middleware
- JWT authentication
- OpenAPI client generation
References
Official Docs
Tutorials
Tools
- FastAPI CLI - Development server
- Swagger UI - Built-in docs
Meta: Skill Quality
Completeness: ✅ Comprehensive (9/9 sections)
Karpathy Principles: ✅ 5 mentions
Code Examples: ✅ 20+ working examples
Production Tested: ✅ Used in MemoryRelay API
Last Updated: 2026-04-13
Coverage:
- ✅ Application setup and lifespan
- ✅ Dependency injection
- ✅ Request validation (Pydantic)
- ✅ Error handling
- ✅ Pagination
- ✅ Background tasks
- ✅ File uploads
- ✅ WebSocket support
- ✅ CORS configuration
- ✅ Async/await best practices
Skill Level: Intermediate
Time to Learn: 4-6 hours
Prerequisites Met: Python, async/await, type hints
Known Gaps: None - production-ready
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

