Fastapi
npx -y skills add muhammederem/chief --skill fastapiAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
12.9 KB, ~3.1k tokens by cl100k_base, as published. Nobody here has run it
FastAPI Framework
Overview
FastAPI is a modern, fast web framework for building APIs with Python based on standard Python type hints. It provides automatic validation, serialization, and interactive API documentation.
Installation
pip install fastapi uvicorn[standard]
pip install pydantic pydantic-settings
Basic Application
Hello World
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
Run Server
uvicorn main:app --reload
# Or with specific host/port
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
Project Structure
Recommended Structure
myapp/
├── app/
│ ├── __init__.py
│ ├── main.py # Application entry
│ ├── api/
│ │ ├── v1/
│ │ │ ├── __init__.py
│ │ │ ├── endpoints/ # API endpoints
│ │ │ └── router.py # API router
│ ├── core/
│ │ ├── config.py # Configuration
│ │ ├── security.py # Security
│ │ └── deps.py # Dependencies
│ ├── models/ # Database models
│ ├── schemas/ # Pydantic schemas
│ ├── services/ # Business logic
│ └── db/
│ └── database.py # Database connection
├── tests/
├── alembic.ini
└── requirements.txt
Main Application
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.api.v1.router import api_router
app = FastAPI(
title="My API",
description="API description",
version="1.0.0"
)
# CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Include routers
app.include_router(api_router, prefix="/api/v1")
Pydantic Schemas
Request/Response Models
from pydantic import BaseModel, EmailStr, Field
from typing import Optional, List
from datetime import datetime
class UserBase(BaseModel):
email: EmailStr
name: str = Field(..., min_length=1, max_length=100)
class UserCreate(UserBase):
password: str = Field(..., min_length=8)
class UserUpdate(BaseModel):
name: Optional[str] = None
email: Optional[EmailStr] = None
class UserResponse(UserBase):
id: int
created_at: datetime
is_active: bool
class Config:
from_attributes = True # For ORM models
Advanced Schemas
from enum import Enum
class Status(str, Enum):
ACTIVE = "active"
INACTIVE = "inactive"
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float = Field(..., gt=0)
tax: Optional[float] = None
tags: List[str] = []
status: Status = Status.INACTIVE
class Config:
json_schema_extra = {
"example": {
"name": "Item name",
"price": 10.5,
"tags": ["electronics", "tech"]
}
}
Dependency Injection
Dependencies
from fastapi import Depends, Header, HTTPException, status
async def get_db():
"""Database session dependency"""
db = SessionLocal()
try:
yield db
finally:
db.close()
async def get_current_user(
token: str = Header(...),
db: Session = Depends(get_db)
):
"""Get authenticated user"""
user = verify_token(token, db)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid credentials"
)
return user
# Use in endpoint
@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_user)):
return current_user
Class-based Dependencies
class CommonQueryParams:
def __init__(
self,
skip: int = 0,
limit: int = 100,
sort: str = "created_at"
):
self.skip = skip
self.limit = limit
self.sort = sort
@app.get("/items/")
async def read_items(commons: CommonQueryParams = Depends()):
return {"skip": commons.skip, "limit": commons.limit}
Database Integration
SQLAlchemy Setup
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "postgresql://user:pass@localhost/db"
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
Model Definition
from sqlalchemy import Column, Integer, String, Boolean, DateTime
from sqlalchemy.sql import func
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
email = Column(String, unique=True, index=True, nullable=False)
name = Column(String, nullable=False)
hashed_password = Column(String, nullable=False)
is_active = Column(Boolean, default=True)
created_at = Column(DateTime(timezone=True), server_default=func.now())
CRUD Operations
from typing import Generic, TypeVar, Type, List
from pydantic import BaseModel
ModelType = TypeVar("ModelType", bound=Base)
CreateSchemaType = TypeVar("CreateSchemaType", bound=BaseModel)
UpdateSchemaType = TypeVar("UpdateSchemaType", bound=BaseModel)
class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
def __init__(self, model: Type[ModelType]):
self.model = model
def get(self, db: Session, id: int) -> Optional[ModelType]:
return db.query(self.model).filter(self.model.id == id).first()
def get_multi(
self, db: Session, skip: int = 0, limit: int = 100
) -> List[ModelType]:
return db.query(self.model).offset(skip).limit(limit).all()
def create(
self, db: Session, obj_in: CreateSchemaType
) -> ModelType:
obj_in_data = obj_in.dict()
db_obj = self.model(**obj_in_data)
db.add(db_obj)
db.commit()
db.refresh(db_obj)
return db_obj
def update(
self,
db: Session,
db_obj: ModelType,
obj_in: UpdateSchemaType
) -> ModelType:
obj_data = obj_in.dict(exclude_unset=True)
for field in obj_data:
setattr(db_obj, field, obj_data[field])
db.add(db_obj)
db.commit()
db.refresh(db_obj)
return db_obj
def delete(self, db: Session, id: int) -> ModelType:
obj = db.query(self.model).get(id)
db.delete(obj)
db.commit()
return obj
Authentication
JWT Authentication
from datetime import datetime, timedelta
from jose import JWTError, jwt
from passlib.context import CryptContext
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def verify_password(plain_password, hashed_password):
return pwd_context.verify(plain_password, hashed_password)
def get_password_hash(password):
return pwd_context.hash(password)
def create_access_token(data: dict):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
@app.post("/token")
async def login(
form_data: OAuth2PasswordRequestForm = Depends(),
db: Session = Depends(get_db)
):
user = authenticate_user(db, form_data.username, form_data.password)
if not user:
raise HTTPException(status_code=400, detail="Incorrect email or password")
access_token = create_access_token(data={"sub": user.email})
return {"access_token": access_token, "token_type": "bearer"}
Protected Routes
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
security = HTTPBearer()
async def get_current_user(
credentials: HTTPAuthorizationCredentials = Depends(security),
db: Session = Depends(get_db)
):
token = credentials.credentials
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
email: str = payload.get("sub")
except JWTError:
raise HTTPException(status_code=403, detail="Invalid token")
user = get_user_by_email(db, email=email)
if not user:
raise HTTPException(status_code=404, detail="User not found")
return user
RESTful CRUD Endpoints
Complete CRUD
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
router = APIRouter(prefix="/items", tags=["items"])
@router.post("/", response_model=ItemResponse)
async def create_item(
item: ItemCreate,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""Create item"""
return crud.item.create(db, item)
@router.get("/", response_model=List[ItemResponse])
async def list_items(
skip: int = 0,
limit: int = 100,
db: Session = Depends(get_db)
):
"""List items with pagination"""
return crud.item.get_multi(db, skip=skip, limit=limit)
@router.get("/{item_id}", response_model=ItemResponse)
async def get_item(
item_id: int,
db: Session = Depends(get_db)
):
"""Get single item"""
item = crud.item.get(db, item_id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
return item
@router.put("/{item_id}", response_model=ItemResponse)
async def update_item(
item_id: int,
item_update: ItemUpdate,
db: Session = Depends(get_db)
):
"""Update item"""
item = crud.item.get(db, item_id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
return crud.item.update(db, item, item_update)
@router.delete("/{item_id}")
async def delete_item(
item_id: int,
db: Session = Depends(get_db)
):
"""Delete item"""
item = crud.item.get(db, item_id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
crud.item.delete(db, item_id)
return {"message": "Item deleted"}
Advanced Features
Background Tasks
from fastapi import BackgroundTasks
def send_email(email: str, message: str):
# Send email logic
pass
@router.post("/signup")
async def signup(
email: str,
background_tasks: BackgroundTasks
):
background_tasks.add_task(send_email, email, "Welcome!")
return {"message": "Signup successful"}
WebSockets
from fastapi import WebSocket
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Message received: {data}")
File Upload
from fastapi import UploadFile, File
@router.post("/upload")
async def upload_file(file: UploadFile = File(...)):
contents = await file.read()
# Save file
return {"filename": file.filename}
Exception Handlers
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
@app.exception_handler(ValueError)
async def value_error_handler(request: Request, exc: ValueError):
return JSONResponse(
status_code=400,
content={"detail": str(exc)}
)
Middleware
Custom Middleware
from fastapi import Request
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
response.headers["X-Process-Time"] = str(process_time)
return response
Testing
Test Client
from fastapi.testclient import TestClient
from app.main import app
client = TestClient(app)
def test_read_item():
response = client.get("/items/1")
assert response.status_code == 200
assert response.json()["id"] == 1
Best Practices
1. Project Structure
- Separate concerns (routes, models, services)
- Use dependency injection
- Keep business logic in services
2. Validation
- Use Pydantic for all input/output
- Define custom validators
- Provide examples in schemas
3. Error Handling
- Use appropriate HTTP status codes
- Provide clear error messages
- Handle exceptions globally
4. Performance
- Use async/await
- Optimize database queries
- Cache frequently accessed data
- Use pagination
5. Security
- Enable CORS properly
- Use HTTPS in production
- Validate and sanitize inputs
- Implement rate limiting
6. Documentation
- Use docstrings for endpoints
- Provide request/response examples
- Document authentication
Integration
- PostgreSQL: SQLAlchemy models
- MongoDB: Motor for async
- Redis: Caching and sessions
- Docker: Containerization
- AWS Lambda: Serverless deployment
Gives 0 of the 12 instructions most apis services skills give in ~3.1k tokens
Counted across 424 of the 426 authors here whose files we hold, read 2026-08-06
- use plural nouns for resource namesin 41 of 424, across 32 files
- use cursor-based pagination for large datasetsin 35 of 424, across 20 files
- include rate limit headers in responsesin 25 of 424, across 13 files
- Use kebab-case for multi-word resourcesin 23 of 424, across 13 files
- version APIs in the URL pathin 19 of 424, across 9 files
- use semantic HTTP status codesin 18 of 424, across 8 files
- verify webhook signaturesin 18 of 424, across 11 files
- use query parameters for filteringin 17 of 424, across 6 files
- use async database operationsin 14 of 424, across 7 files
- wrap successful responses in a data fieldin 13 of 424, across 3 files
- prefix sorting parameters with a hyphen for descending orderin 13 of 424, across 3 files
- set appropriate HTTP status codesin 13 of 424, across 6 files
Said here and by no other author read
- Install FastAPI, Uvicorn, and Pydantic
- Separate database models from Pydantic schemas
- Define CRUD operations in service classes
- Use TestClient for testing
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.