关于 fastapi-service
用于构建 FastAPI 服务的技能,涵盖 JWT 身份验证、structlog 结构化日志和 Prometheus 指标。还提供依赖注入、生命周期管理及健康检查等服务实现模式。
主要功能
- 01配置 JWT 身份验证
- 02使用 structlog 记录结构化日志
- 03通过 Prometheus 自动采集路由指标
- 04采用应用生命周期管理启动与关闭
- 05提供健康检查端点实践
适用场景
- 01搭建带身份验证的 FastAPI 服务
- 02为 API 添加结构化日志和指标
- 03设置服务就绪与存活检查
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ brojonat/ llmsrules --skill fastapi-service安装后在 Claude Code 中输入/fastapi-service确认已加载。
详细介绍
FastAPI 服务
构建生产级 FastAPI 服务,支持 JWT 身份验证、通过 structlog 实现结构化日志记录,以及 Prometheus 指标。
快速开始
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)
依赖项
uv add fastapi "uvicorn[standard]" "python-jose[cryptography]" prometheus-fastapi-instrumentator structlog
环境配置
创建 .env.server:
export AUTH_SECRET="your-strong-shared-secret"
export LOG_LEVEL=INFO
export LOG_JSON=false
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
测试身份验证
生成测试令牌:
uv run python - <<'PY'
from jose import jwt
print(jwt.encode({"sub":"alice","role":"admin"}, "your-strong-shared-secret", algorithm="HS256"))
PY
调用经过身份验证的端点:
curl -H "Authorization: Bearer <token>" http://localhost:8000/whoami
关键模式
- 生命周期:使用
@asynccontextmanager处理启动和关闭,不要使用已弃用的on_event - 依赖注入:使用
Depends()处理身份验证、数据库连接和共享资源 - 结构化日志记录:在模块级别配置一次 structlog;为每个请求绑定上下文变量
- 指标:
prometheus-fastapi-instrumentator会自动为所有路由添加监控 - 健康检查:始终公开
/healthz,供 k8s 就绪和存活探针使用
维护记录
修改服务后,更新相邻的 README.md,以反映当前的 API 接口。
评论
支持 Markdown