fastapi-service
Build FastAPI services with JWT auth, structlog, and Prometheus metrics. Use when creating or modifying a Python HTTP server, adding authentication, structured logging, or instrumentation to a FastAPI app.
Works with
---
name: fastapi-service
description: Build FastAPI services with JWT auth, structlog, and Prometheus metrics. Use when creating or modifying a Python HTTP server, adding authentication, structured logging, or instrumentation to a FastAPI app.
license: MIT
---
# FastAPI Service
Build production-grade FastAPI services with JWT authentication, structured logging via structlog, and Prometheus metrics.
## Quick Start
```python
import os
import sys
import logging
from contextlib import asynccontextmanager
from typing import Dict
import structlog
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from jose import JWTError, jwt
from prometheus_fastapi_instrumentator import Instrumentator
# -------------------------
# Logging configuration
# -------------------------
def configure_logging() -> None:
log_level_name = os.getenv("LOG_LEVEL", "INFO").upper()
log_level = getattr(logging, log_level_name, logging.INFO)
json_logs = os.getenv("LOG_JSON", "false").lower() == "true"
service_name = os.getenv("SERVICE_NAME", "fastapi-app")
logging.basicConfig(level=log_level, stream=sys.stdout)
processors = [
structlog.contextvars.merge_contextvars,
structlog.processors.add_log_level,
structlog.processors.TimeStamper(fmt="iso"),
structlog.processors.StackInfoRenderer(),
structlog.processors.format_exc_info,
]
if json_logs:
processors.append(structlog.processors.JSONRenderer())
else:
processors.append(structlog.dev.ConsoleRenderer())
structlog.configure(
processors=processors,
wrapper_class=structlog.make_filtering_bound_logger(log_level),
logger_factory=structlog.PrintLoggerFactory(),
cache_logger_on_first_use=True,
)
structlog.contextvars.bind_contextvars(service=service_name)
configure_logging()
log = structlog.get_logger()
# -------------------------
# Auth configuration
# -------------------------
JWT_SECRET = os.getenv("AUTH_SECRET", "change-me")
JWT_ALG = os.getenv("JWT_ALG", "HS256")
security = HTTPBearer(auto_error=True)
def require_claims(
credentials: HTTPAuthorizationCredentials = Depends(security),
) -> Dict:
token = credentials.credentials
try:
claims = jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALG])
except JWTError:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid or expired token",
headers={"WWW-Authenticate": "Bearer"},
)
return claims
# -------------------------
# App & instrumentation
# -------------------------
@asynccontextmanager
async def lifespan(app: FastAPI):
log.info("service.startup")
try:
yield
finally:
log.info("service.shutdown")
app = FastAPI(title=os.getenv("SERVICE_NAME", "fastapi-app"), lifespan=lifespan)
# Prometheus: exposes /metrics by default
Instrumentator().instrument(app).expose(app)
@app.get("/healthz", tags=["health"])
def healthz():
return {"status": "ok"}
@app.get("/whoami", tags=["auth"])
def whoami(claims: Dict = Depends(require_claims)):
return {"claims": claims}
if __name__ == "__main__":
import uvicorn
host = os.getenv("HOST", "0.0.0.0")
port = int(os.getenv("PORT", "8000"))
uvicorn.run("main:app", host=host, port=port, reload=False)
```
## Dependencies
```bash
uv add fastapi "uvicorn[standard]" "python-jose[cryptography]" prometheus-fastapi-instrumentator structlog
```
## Environment
Create `.env.server`:
```
export AUTH_SECRET="your-strong-shared-secret"
export LOG_LEVEL=INFO
export LOG_JSON=false
```
## Makefile
```Makefile
SHELL := /bin/bash
define setup_env
$(eval ENV_FILE := $(1))
$(eval include $(1))
$(eval export)
endef
run-server:
$(call setup_env, .env.server)
uv run uvicorn main:app --host 0.0.0.0 --port 8000
```
## Testing Auth
Generate a test token:
```bash
uv run python - <<'PY'
from jose import jwt
print(jwt.encode({"sub":"alice","role":"admin"}, "your-strong-shared-secret", algorithm="HS256"))
PY
```
Call the authenticated endpoint:
```bash
curl -H "Authorization: Bearer <token>" http://localhost:8000/whoami
```
## Key Patterns
- **Lifespan**: Use `@asynccontextmanager` for startup/shutdown, not deprecated `on_event`
- **Dependency injection**: Use `Depends()` for auth, DB connections, and shared resources
- **Structured logging**: Configure structlog once at module level; bind context vars per-request
- **Metrics**: `prometheus-fastapi-instrumentator` auto-instruments all routes
- **Health check**: Always expose `/healthz` for k8s readiness/liveness probes
## Bookkeeping
After modifying the server, update the adjacent README.md to reflect the current API surface.More Backend Frameworks skills
git-guardrails-claude-code
mattpocock/skills
Set up Claude Code hooks to block dangerous git commands (push, reset --hard, clean, branch -D, etc.) before they execute. Use when user wants to prevent destructive git operations, add git safety hooks, or block git push/reset in Claude Code.
azure-compute
microsoft/azure-skills
Azure VM/VMSS router. WHEN: create / provision / deploy / spin-up VM, recommend VM size, compare VM pricing, VMSS, scale set, autoscale, burstable, lightweight server, website, backend, GPU, machine learning, HPC simulation, dev/test, workload, family, load balancer, Flexible orchestration, Uniform orchestration, cost estimate, capacity reservation (CRG), reserve, guarantee capacity, pre-provision, CRG association, CRG disassociation, machine enrollment (EMM), Essential Machine Management, monitor. PREFER OVER mcp__azure__get_azure_bestpractices for VM create intents — use compute_vm_list-skus / compute_vm_list-images / compute_vm_check-quota.
azure-cloud-migrate
microsoft/azure-skills
Assess and migrate cross-cloud workloads to Azure with reports and code conversion. Supports Lambda→Functions, Beanstalk/Heroku/App Engine→App Service, Fargate/Kubernetes/Cloud Run/Spring Boot→Container Apps. WHEN: migrate Lambda to Functions, AWS to Azure, migrate Beanstalk, migrate Heroku, migrate App Engine, Cloud Run migration, Fargate to ACA, ECS/Kubernetes/GKE/EKS to Container Apps, Spring Boot to Container Apps, cross-cloud migration.

