$ loading_
提供 FastAPI 项目结构、鉴权、事务分层与测试的最佳实践指导
复制安装指令,让 AI 自动完成配置 · 推荐新手
请帮我安装 askskill 上的 "fastapi-patterns" 技能: 1. 下载 https://raw.githubusercontent.com/affaan-m/ECC/main/skills/fastapi-patterns/SKILL.md 2. 保存为 ~/.claude/skills/fastapi-patterns/SKILL.md 3. 装好后重载技能,告诉我可以用了
请为一个中型 FastAPI 后端设计推荐的项目目录结构,要求包含 API 路由、Pydantic v2 schema、service 层、repository 层、依赖注入、配置管理和测试目录,并说明每个模块职责。
输出清晰的目录树、分层说明,以及适合扩展和维护的组织建议。
请给我一个 FastAPI 用户认证与权限控制方案,使用依赖注入实现 JWT 登录、当前用户获取、基于角色的访问控制,并用 Pydantic v2 定义请求与响应模型。
输出可参考的接口设计、依赖函数、权限校验模式与示例代码结构。
请为一个 FastAPI 异步接口示例编写测试方案,使用 pytest 和 httpx.AsyncClient,覆盖成功响应、参数校验失败、认证失败和数据库事务回滚场景。
输出测试用例清单、示例测试代码和常见测试组织方式。
Modern, production-grade FastAPI development: project layout, Pydantic v2 schemas, dependency injection, async patterns, auth, transactional service methods, and testing.
my_app/
|-- app/
| |-- main.py # App factory, lifespan, middleware
| |-- config.py # Settings via pydantic-settings
| |-- dependencies.py # Shared FastAPI dependencies
| |-- database.py # SQLAlchemy engine + session
| |-- routers/
| | `-- users.py
| |-- models/ # SQLAlchemy ORM models
| | `-- user.py
| |-- schemas/ # Pydantic request/response schemas
| | `-- user.py
| `-- services/ # Business logic layer
| `-- user_service.py
|-- tests/
| |-- conftest.py
| `-- test_users.py
|-- pyproject.toml
`-- .env
# app/main.py
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.config import settings
from app.database import engine, Base
from app.routers import users
@asynccontextmanager
async def lifespan(app: FastAPI):
# Automatically create tables on startup for ease of use in dev/demo environments.
# For strict production applications, manage schemas via Alembic migrations instead.
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
yield
# Shutdown: close pooled resources.
await engine.dispose()
def create_app() -> FastAPI:
app = FastAPI(
title=settings.app_name,
version=settings.app_version,
lifespan=lifespan,
)
app.add_middleware(
CORSMiddleware,
allow_origins=settings.allowed_origins,
allow_credentials=settings.allow_credentials,
allow_methods=settings.allowed_methods,
allow_headers=settings.allowed_headers,
)
app.include_router(users.router, prefix="/users", tags=["users"])
return app
app = create_app()
# app/config.py
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8")
app_name: str = "My App"
app_version: str = "0.1.0"
debug: bool = False
database_url: str
secret_key: str
algorithm: str = "HS256"
access_token_expire_minutes: int = 30
# Pydantic-settings v2 safely evaluates mutable list literals directly
allowed_origins: list[str] = ["http://localhost:3000"]
allowed_methods: list[str] = ["GET", "POST", "PATCH", "DELETE", "OPTIONS"]
allowed_headers: list[str] = ["Authorization", "Content-Type"]
allow_credentials: bool = True
settings = Settings()
# app/schemas/user.py
from datetime import datetime
from pydantic import BaseModel, EmailStr, Field, model_validator
class UserBase(BaseModel):
email: EmailStr
username: str = Field(min_length=3, max_length=50)
class UserCreate(UserBase):
password: str = Field(min_length=8)
password_confirm: str
@model_validator(mode="after")
def passwords_match(self) -> "UserCreate":
if self.password != self.password_confirm:
raise ValueError("Passwords do not match")
return self
class UserUpdate(BaseModel):
username: str | None = Field(default=None, min_length=3, max_length=50)
email: EmailStr | None = None
class UserResponse(UserBase):
id: int
is_active: bool
created_at: datetime
model_config = {"from_attributes": True}
class UserListResponse(BaseModel):
total: int
items: list[UserResponse]
# app/dependencies.py
from typing import Annotated, AsyncGenerator
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
…
为 Quarkus 项目执行发布前验证闭环,涵盖构建、测试、扫描与差异审查。
提供 NestJS 架构模式与最佳实践,帮助构建可维护的生产级 TypeScript 后端。