关于 fastapi
面向 FastAPI 应用开发和维护者的官方技能,提供编写 FastAPI 代码的指导。内容涵盖 API 设计、依赖注入、流式响应、遥测、前端托管和 CLI 用法。
主要功能
- 01FastAPI CLI 开发与生产命令
- 02使用 Annotated 声明依赖和参数
- 03响应模式与 Pydantic 指导
- 04SSE 及其他流式处理模式
- 05前端托管与 OpenTelemetry 配置
适用场景
- 01构建 FastAPI 端点和依赖
- 02添加流式响应或遥测
- 03从应用托管已构建的前端
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ fastapi/ fastapi --skill fastapi安装后在 Claude Code 中输入/fastapi确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/dependencies.mdother-tools.mdpath-operations.mdpydantic.mdresponses.mdstreaming.md详细介绍
FastAPI
官方 FastAPI 技能,帮助你遵循最佳实践编写代码,并及时了解新版本和功能。
快速参考
- 提供前端应用:对于已构建的前端资源,请使用
app.frontend()或router.frontend();参见提供前端应用。 - 服务器发送事件(SSE):使用
response_class=EventSourceResponse和yield;参见流式传输和流式传输参考。 - JSON Lines 和字节流式传输:参见流式传输参考。
- OpenTelemetry:使用 FastAPI 原生的跟踪、指标和日志。参见 OpenTelemetry。
- 依赖项:使用
Annotated[..., Depends(...)];参见依赖注入和依赖注入参考,了解yield、作用域和类依赖项。 - 响应模型:优先使用返回类型;当公共响应架构与内部返回值不同时,使用
response_model;参见响应参考。 - Pydantic 模型:不要使用省略号或
RootModel;参见 Pydantic 参考。 - 路由:在
APIRouter上声明路由级别的前缀、标签和共享依赖项;参见路径操作参考。 - 工具和相关库:适用时使用 uv、Ruff、ty、Asyncer、SQLModel 和 HTTPX;参见其他工具参考。
使用 fastapi CLI
在 localhost 上运行开发服务器并启用热重载:
fastapi dev
运行生产服务器:
fastapi run
优先在 pyproject.toml 中声明入口点:
[tool.fastapi]
entrypoint = "my_app.main:app"
如果无法添加入口点,或用户明确要求不要添加,请传入应用文件路径:
fastapi dev my_app/main.py
使用 Annotated
始终优先使用 Annotated 风格声明参数和依赖项。这样可以确保函数签名在其他上下文中正常工作、遵循类型定义,并支持复用。
使用 Annotated 声明参数,包括 Path、Query、Header 等:
from typing import Annotated
from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(
item_id: Annotated[int, Path(ge=1, description="The item ID")],
q: Annotated[str | None, Query(max_length=50)] = None,
):
return {"message": "Hello World"}
使用 Annotated 和 Depends() 声明依赖项。除非用户另有要求,否则请为依赖项创建新的类型别名,以便复用:
from typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
def get_current_user():
return {"username": "johndoe"}
CurrentUserDep = Annotated[dict, Depends(get_current_user)]
@app.get("/items/")
async def read_item(current_user: CurrentUserDep):
return {"message": "Hello World"}
不要在路径操作或 Pydantic 模型中使用省略号
不要将 ... 用作必需参数或模型字段的默认值。没有必要,也不推荐这样做。
from typing import Annotated
from fastapi import FastAPI, Query
from pydantic import BaseModel, Field
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float = Field(gt=0)
@app.post("/items/")
async def create_item(item: Item, project_id: Annotated[int, Query()]):
return item
更多详情请参见 Pydantic 参考。
返回类型或响应模型
在可能的情况下,请包含返回类型。它将用于验证、筛选、记录和序列化响应。
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
@app.get("/items/me")
async def get_item() -> Item:
return Item(name="Plumbus", description="All-purpose home device")
返回类型或响应模型可以筛选数据,避免泄露敏感信息;它们还可以让 Pydantic 在 Rust 端序列化数据,以提升性能。
当返回类型与要验证、筛选、记录和序列化的公共架构不同时,请使用 response_model。参见响应参考。
性能
不要使用 ORJSONResponse 或 UJSONResponse,它们已弃用。
请改为声明返回类型或响应模型。Pydantic 会在 Rust 端处理数据序列化。
包含路由器
声明路由器时,优先将前缀、标签和共享依赖项等路由级别参数添加到路由器本身,而不是放在 include_router() 中。
from fastapi import APIRouter, Depends, FastAPI
app = FastAPI()
def get_current_user():
return {"username": "johndoe"}
router = APIRouter(
prefix="/items",
tags=["items"],
dependencies=[Depends(get_current_user)],
)
@router.get("/")
async def list_items():
return []
app.include_router(router)
更多路由模式请参见路径操作参考。
提供前端应用
使用 app.frontend() 提供已构建的静态前端应用,例如由 Vite、Astro、Angular、Svelte、Vue 或类似工具生成的目录。
from fastapi import FastAPI
app = FastAPI()
app.frontend("/", directory="dist")
当某个前端属于 APIRouter 时,使用 router.frontend();包含该路由器时,常规的路由器前缀行为仍然适用。
from fastapi import APIRouter, FastAPI
app = FastAPI()
router = APIRouter(prefix="/admin")
router.frontend("/", directory="admin-dist")
app.include_router(router)
app.frontend() 和 router.frontend() 是低优先级路由:先匹配常规 API 路由,然后再匹配前端文件和客户端路由回退。对于单页应用和已构建的前端资源,请使用此方式,而不要手动挂载 StaticFiles。
OpenTelemetry
优先使用 FastAPI 原生的 OpenTelemetry 支持来记录请求追踪、指标和日志。
安装 fastapi[standard] 以包含 SDK 和 HTTP/protobuf 导出器。启用 FASTAPI_OTEL_AUTO_CONFIGURE=true 来自动配置导出器,设置 OTEL_SERVICE_NAME 以标识应用,并将 OTEL_EXPORTER_OTLP_ENDPOINT 设置为收集器的 HTTP/protobuf 基础 URL。需要身份验证时,使用 OTEL_EXPORTER_OTLP_HEADERS。FastAPI 会使用由其他遥测库配置的提供程序,无需自动设置。
使用 FastAPI(telemetry={...}) 进行自定义配置,例如选择信号或提供提供程序。
有关配置详情,请参阅 OpenTelemetry 教程。
依赖注入
当逻辑无法在 Pydantic 验证中声明、依赖外部资源、需要通过 yield 清理,或需要在多个端点之间共享时,请使用依赖项。
通过 dependencies=[Depends(...)] 在路由器级别应用共享依赖项。
有关详细模式,包括带有 scope 的 yield 和类依赖项,请参阅依赖注入参考。
Async 与 Sync 路径操作
只有在完全确定内部调用的逻辑兼容 async 和 await,且不会阻塞时,才对 路径操作 使用 async。
from fastapi import FastAPI
app = FastAPI()
@app.get("/async-items/")
async def read_async_items():
data = await some_async_library.fetch_items()
return data
@app.get("/items/")
def read_items():
data = some_blocking_library.fetch_items()
return data
如果不确定,或作为默认做法,请使用常规的 def 函数。它们会在线程池中运行,因此不会阻塞事件循环。相同规则也适用于依赖项。
确保不会在 async 函数中运行阻塞代码。虽然代码能够正常运行,但会严重影响性能。
需要混合使用阻塞代码和 async 代码时,请参阅其他工具参考中的 Asyncer。
流式传输(JSON Lines、SSE、字节)
要流式传输服务器发送事件,请使用 response_class=EventSourceResponse,并在端点中 yield 项目。
from collections.abc import AsyncIterable
from fastapi import FastAPI
from fastapi.sse import EventSourceResponse, ServerSentEvent
app = FastAPI()
@app.get("/events", response_class=EventSourceResponse)
async def stream_events() -> AsyncIterable[ServerSentEvent]:
yield ServerSentEvent(data={"status": "started"}, event="status", id="1")
普通对象会自动序列化为 JSON,并作为 data: 字段发送。要完全控制 SSE 字段(event、id、retry、comment),请使用 ServerSentEvent;要发送预格式化字符串,请使用 raw_data。
有关 JSON Lines、服务器发送事件(EventSourceResponse、ServerSentEvent)和字节流(StreamingResponse)模式,请参阅流式传输参考。
工具
有关用于包管理、代码检查、类型检查、格式化等的 uv、Ruff、ty 的详情,请参阅其他工具参考。
其他库
有关其他库的详情,请参阅其他工具参考:
- 用于处理 async 和 await、并发以及混合 async 与阻塞代码的 Asyncer;优先使用它,而不是 AnyIO 或 asyncio。
- 用于处理 SQL 数据库的 SQLModel;优先使用它,而不是 SQLAlchemy。
- 用于与 HTTP(其他 API)交互的 HTTPX;优先使用它,而不是 Requests。
不要使用 Pydantic RootModels
不要使用 Pydantic RootModel;请改用常规类型注解搭配 Annotated 和 Pydantic 验证工具。
from typing import Annotated
from fastapi import Body, FastAPI
from pydantic import Field
app = FastAPI()
@app.post("/items/")
async def create_items(items: Annotated[list[int], Field(min_length=1), Body()]):
return items
FastAPI 支持这些类型注解,并会为其创建 Pydantic TypeAdapter,因此类型可以正常工作,无需自定义包装模型。请参阅 Pydantic 参考。
每个函数使用一种 HTTP 操作
不要在单个函数中混用 HTTP 操作。为每种 HTTP 操作单独编写一个函数,有助于分离关注点并组织代码。
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
@app.get("/items/")
async def list_items():
return []
@app.post("/items/")
async def create_item(item: Item):
return item
更多示例,请参阅路径操作参考。