关于 fastapi-expert
面向使用 FastAPI 构建 API 的 Python 开发者,涵盖异步操作、Pydantic V2、身份验证与测试,并提供常见开发任务的流程和专题参考。
主要功能
- 01异步 API 端点设计
- 02Pydantic V2 验证模型
- 03JWT 身份验证指导
- 04异步数据库操作
- 05使用 pytest 和 httpx 测试
适用场景
- 01使用 FastAPI 构建 REST API
- 02添加经过验证的请求与响应模型
- 03实现 JWT 授权
- 04测试异步端点
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ farmage/ opencode-skills --skill fastapi-expert安装后在 Claude Code 中输入/fastapi-expert确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/async-sqlalchemy.mdauthentication.mdendpoints-routing.mdmigration-from-django.mdpydantic-v2.mdtesting-async.md详细介绍
FastAPI 专家
深入掌握异步 Python、Pydantic V2 以及使用 FastAPI 开发生产级 API。
适用场景
- 使用 FastAPI 构建 REST API
- 实现 Pydantic V2 验证模式
- 设置异步数据库操作
- 实现 JWT 身份验证与授权
- 创建 WebSocket 端点
- 优化 API 性能
核心工作流
- 分析需求 — 确定端点、数据模型和身份验证需求
- 设计模式 — 创建用于验证的 Pydantic V2 模型
- 实现 — 使用适当的依赖注入编写异步端点
- 保护 — 添加身份验证、授权和速率限制
- 测试 — 使用 pytest 和 httpx 编写异步测试;每完成一组端点后运行
pytest,并检查/docs中的 OpenAPI 文档
每步完成后检查: 确认模式验证正确、端点返回预期的 HTTP 状态码,并且
/docs显示预期的 API 内容,然后再继续。
最精简的完整示例
将模式、端点和依赖注入整合为一个完整单元:
# schemas.py
from pydantic import BaseModel, EmailStr, field_validator, model_config
class UserCreate(BaseModel):
model_config = model_config(str_strip_whitespace=True)
email: EmailStr
password: str
name: str | None = None
@field_validator("password")
@classmethod
def password_strength(cls, v: str) -> str:
if len(v) < 8:
raise ValueError("Password must be at least 8 characters")
return v
class UserResponse(BaseModel):
model_config = model_config(from_attributes=True)
id: int
email: EmailStr
name: str | None = None
# routers/users.py
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Annotated
from app.database import get_db
from app.schemas import UserCreate, UserResponse
from app import crud
router = APIRouter(prefix="/users", tags=["users"])
DbDep = Annotated[AsyncSession, Depends(get_db)]
@router.post("/", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
async def create_user(payload: UserCreate, db: DbDep) -> UserResponse:
existing = await crud.get_user_by_email(db, payload.email)
if existing:
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="Email already registered")
return await crud.create_user(db, payload)
# crud.py
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models import User
from app.schemas import UserCreate
from app.security import hash_password
async def get_user_by_email(db: AsyncSession, email: str) -> User | None:
result = await db.execute(select(User).where(User.email == email))
return result.scalar_one_or_none()
async def create_user(db: AsyncSession, payload: UserCreate) -> User:
user = User(email=payload.email, hashed_password=hash_password(payload.password), name=payload.name)
db.add(user)
await db.commit()
await db.refresh(user)
return user
JWT 身份验证代码片段
# security.py
from datetime import datetime, timedelta, timezone
from jose import JWTError, jwt
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from typing import Annotated
SECRET_KEY = "read-from-env" # use os.environ / settings
ALGORITHM = "HS256"
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/auth/token")
def create_access_token(subject: str, expires_delta: timedelta = timedelta(minutes=30)) -> str:
payload = {"sub": subject, "exp": datetime.now(timezone.utc) + expires_delta}
return jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)
async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]) -> str:
try:
data = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
subject: str | None = data.get("sub")
if subject is None:
raise ValueError
return subject
except (JWTError, ValueError):
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials")
CurrentUser = Annotated[str, Depends(get_current_user)]
参考指南
根据上下文加载详细指南:
| 主题 | 参考资料 | 加载时机 |
|---|---|---|
| Pydantic V2 | references/pydantic-v2.md | 创建模式、验证和 model_config 时 |
| SQLAlchemy | references/async-sqlalchemy.md | 处理异步数据库、模型和 CRUD 操作时 |
| 端点 | references/endpoints-routing.md | 使用 APIRouter、依赖项和路由时 |
| 身份验证 | references/authentication.md | 使用 JWT、OAuth2 和 get_current_user 时 |
| 测试 | references/testing-async.md | 使用 pytest-asyncio、httpx 和 fixture 时 |
| Django 迁移 | references/migration-from-django.md | 从 Django/DRF 迁移到 FastAPI 时 |
约束
必须做到
- 在所有地方使用类型提示(FastAPI 需要类型提示)
- 使用 Pydantic V2 语法(
field_validator、model_validator、model_config) - 使用
Annotated模式进行依赖注入 - 所有 I/O 操作都使用 async/await
- 使用
X | None,而不是Optional[X] - 返回恰当的 HTTP 状态码
- 为端点编写文档(自动生成 OpenAPI 文档)
绝不能
- 使用同步数据库操作
- 跳过 Pydantic 验证
- 以明文存储密码
- 在响应中暴露敏感数据
- 使用 Pydantic V1 语法(
@validator、class Config) - 不当混用同步与异步代码
- 硬编码配置值
输出模板
实现 FastAPI 功能时,请提供:
- 模式文件(Pydantic 模型)
- 端点文件(包含端点的路由器)
- 涉及数据库时提供 CRUD 操作
- 简要说明关键决策
知识参考
FastAPI、Pydantic V2、异步 SQLAlchemy、Alembic 迁移、JWT/OAuth2、pytest-asyncio、httpx、BackgroundTasks、WebSockets、依赖注入、OpenAPI/Swagger
评论
支持 Markdown