FastAPI:Path Operation Decorator 配置全指南——status_code、tags、summary、description 与 deprecated 元数据
本指南聚焦 FastAPI 中**路径操作装饰器(path operation decorator)**的配置能力:如何通过向 @app.get()、@app.post() 等装饰器传入参数,为每个 API 端点声明响应状态码、分组标签、标题与描述文本,以及标记弃用接口。阅读完本文,你将掌握一套直接作用于 OpenAPI 模式与自动交互式文档的元数据配置方法,让生成的 Swagger UI / ReDoc 文档与团队规范无缝对齐。全文示例均取自本仓库 docs_src/path_operation_configuration/ 目录,示例要求 Python 3.10+(代码中使用 str | None 联合类型语法),并可在本仓库 tests 目录中找到对应回归测试。
关键前提:参数属于装饰器,而非函数
所有配置参数都直接传给 path operation decorator,而不是传给被装饰的 path operation function。即它们书写在 @app.get(...) / @app.post(...) 的括号里,而不是在 async def ... 的函数签名里。
Advertencia(警告):这些参数是传给 path operation decorator 的,不是传给 path operation function 的。写错位置时这些参数不会生效。
从源码实现看,这些参数最终会汇聚到 fastapi/routing.py 的路由注册逻辑中:装饰器在底层通过 APIRouter.add_api_route(...) 构建 APIRoute 实例,并把 tags、deprecated、response_description 等元数据记录到路由对象上,随后在生成 OpenAPI 模式时被读取(对应 response_description: str = "Successful Response"、deprecated: bool | None = None、tags: list[str | Enum] | None = None 等默认签名,见 fastapi/routing.py)。
以下示例共用同一个 Item 请求体模型:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
配置响应状态码:status_code
可以通过 status_code 参数指定 path operation 响应所使用的 HTTP 状态码,它会实际用于 HTTP response,同时也会被加入 OpenAPI 模式(responses 字段)。
可以直接传数字 int,例如 404;如果记不住每个数字对应的语义,可以使用 status 模块中的快捷常量:
from fastapi import FastAPI, status
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
@app.post("/items/", status_code=status.HTTP_201_CREATED)
async def create_item(item: Item) -> Item:
return item
(完整代码见 tutorial001_py310.py)
上例把 POST /items/ 的响应状态码设为 201 Created,比默认的 200 更贴合「资源创建成功」的语义。对应的回归测试 test_tutorial001.py 同时验证了两件事:其一,真实响应状态码确实是 201(assert response.status_code == 201);其二,通过 client.get("/openapi.json") 得到的模式中,paths["/items/"]["post"]["responses"] 下挂着 "201" 键而非 "200",证明该状态码同时写入了 OpenAPI schema。
Nota técnica(技术细节):你也可以使用
from starlette import status。FastAPI 只是出于开发者便利,把同一个starlette.status再以fastapi.status的形式导出,它的源头就是 Starlette 模块。
这意味着两者是同一组常量,fastapi.status.HTTP_201_CREATED 与 starlette.status.HTTP_201_CREATED 指向同一个值,按项目风格二选一即可。
添加分组标签:tags
tags 参数接受一个 str 组成的 list(实践中常常只有一个字符串)。FastAPI 会把 tags 写入 OpenAPI 模式,交互式文档则据此把路径按标签分组展示:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
@app.post("/items/", tags=["items"])
async def create_item(item: Item) -> Item:
return item
@app.get("/items/", tags=["items"])
async def read_items():
return [{"name": "Foo", "price": 42}]
@app.get("/users/", tags=["users"])
async def read_users():
return [{"username": "johndoe"}]
(完整代码见 tutorial002_py310.py)
上面 create_item 与 read_items 都标记了 "items",read_users 标记 "users",Swagger UI 中 /items/ 相关的 GET/POST 路径就会聚合到 items 分组下,/users/ 路径则单独归入 users 分组:
对应测试见 test_tutorial002.py,其中会断言 OpenAPI 模式的 tags 列表与分组结果。
用 Enum 管理 tags,避免拼写漂移
在大型应用中,路径操作会越来越多,tags 也会越积越多。若全靠手写字符串,很容易在多个相关接口上出现 "items" 与 "item" 之类的拼写不一致,导致文档分组混乱。此时把 tags 集中存放进一个 Enum 是更稳妥的做法,FastAPI 对 Enum 的支持与普通字符串完全相同:
from enum import Enum
from fastapi import FastAPI
app = FastAPI()
class Tags(Enum):
items = "items"
users = "users"
@app.get("/items/", tags=[Tags.items])
async def get_items():
return ["Portal gun", "Plumbus"]
@app.get("/users/", tags=[Tags.users])
async def read_users():
return ["Rick", "Morty"]
(完整代码见 tutorial002b_py310.py)
Tags 枚举集中定义了所有合法标签,声明路由时写 tags=[Tags.items] 即可。从 fastapi/routing.py 的类型签名也能印证这一点:tags: list[str | Enum],即列表元素既可以是 str 也可以是 Enum 成员。这样一来,「同一组相关接口始终使用同一个标签」由类型系统与集中定义来保证,而不是依赖每个开发者的记忆。注意传参时仍要放在 list 里(如 tags=[Tags.items])。对应测试见 test_tutorial002b.py。
添加 summary 与 description 元数据
summary 是路径操作在图示文档中显示的短标题;description 则用于承载更长的说明文字:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
@app.post(
"/items/",
summary="Create an item",
description="Create an item with all the information, name, description, price, tax and a set of unique tags",
)
async def create_item(item: Item) -> Item:
return item
(完整代码见 tutorial003_py310.py)
summary 通常保持简洁,类似文档标题;description 可写成较长的单行字符串,也可以继续用「从 docstring 读取描述」的方式承载多行文本。
用 docstring 承载长描述,并支持 Markdown
由于接口描述往往很长、需要跨越多行,直接在装饰器参数里写会非常臃肿。FastAPI 的解决方案是:把描述写进 path operation function 的 docstring(函数体内的首条多行字符串表达式),FastAPI 会自动读取它并当作 description 使用。docstring 里可以书写 Markdown,会被正确解释渲染(渲染时会正确处理 docstring 的缩进):
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
@app.post("/items/", summary="Create an item")
async def create_item(item: Item) -> Item:
"""
Create an item with all the information:
- **name**: each item must have a name
- **description**: a long description
- **price**: required
- **tax**: if the item doesn't have tax, you can omit this
- **tags**: a set of unique tag strings for this item
"""
return item
(完整代码见 tutorial004_py310.py)
注意上例只显式传了 summary,description 完全来自 docstring。docstring 中的 Markdown 列表、粗体、行内代码等语法都会在交互式文档中按语义渲染:
测试层面,test_tutorial003_tutorial004.py 对 tutorial003 与 tutorial004 做了对照断言:两个示例产生的 OpenAPI 模式中 paths["/items/"]["post"]["summary"] 都是 "Create an item",而 description 字段分别取自「装饰器显式传入的字符串」与「docstring(经 textwrap.dedent 去除公共缩进后的文本)」,二者殊途同归,最终都进入 OpenAPI 模式。
单独声明响应描述:response_description
response_description 参数用于指定**响应(response)**的描述文字,它出现在交互式文档每个状态码条目下:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
@app.post(
"/items/",
summary="Create an item",
response_description="The created item",
)
async def create_item(item: Item) -> Item:
"""
Create an item with all the information:
- **name**: each item must have a name
- **description**: a long description
- **price**: required
- **tax**: if the item doesn't have tax, you can omit this
- **tags**: a set of unique tag strings for this item
"""
return item
(完整代码见 tutorial005_py310.py)
Nota(注意):
response_description专门描述 response,而description描述的是整个 path operation,两者指向不同的 OpenAPI 字段,不要混淆。
Consejo(提示):OpenAPI 规范要求每个 path operation 都必须有 response description。因此,如果你没有显式提供,FastAPI 会自动生成默认值
"Successful Response"。这一点同样能从 fastapi/routing.py 的签名默认值response_description: str = "Successful Response"得到印证。
设置 response_description="The created item" 后,交互式文档中 200 状态码条目下方的说明就显示为 The created item(同时文档仍会展示由 Pydantic 模型自动推导的响应体结构与 422 Validation Error 校验失败结构):
标记弃用接口:deprecated
当接口需要被标记为 已弃用(obsolete,官方不推荐继续使用),但又不能立即删除时,给装饰器传 deprecated=True 即可。该参数在交互式文档中会明确标注 deprecated,同时接口仍可正常调用:
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/", tags=["items"])
async def read_items():
return [{"name": "Foo", "price": 42}]
@app.get("/users/", tags=["users"])
async def read_users():
return [{"username": "johndoe"}]
@app.get("/elements/", tags=["items"], deprecated=True)
async def read_elements():
return [{"item_id": "Foo"}]
(完整代码见 tutorial006_py310.py)
以 deprecated=True 标记的 /elements/ 路径会在交互式文档中呈现为灰色弱化样式,并显示 Warning: Deprecated 提示,让使用方(包括人类与代码生成客户端)明确得知该接口已不推荐使用:
把弃用与未弃用的路径操作放在一起对比,灰色弱化与正常高亮的区别非常直观,客户端生成工具也可依据 OpenAPI 中 deprecated: true 字段自动处理:
对应的 test_tutorial006.py 会断言 OpenAPI 模式中 /elements/ 的 GET 操作带上了 deprecated: true。在 fastapi/routing.py 中该参数的类型为 deprecated: bool | None = None,即默认不弃用,传入 True 时才生效。
各配置参数一览
把上文参数汇总如下,均作为 path operation decorator 的命名参数传入:
| 参数 | 类型 | 默认行为 | 作用与落点 |
|---|---|---|---|
status_code |
int |
200 |
设定实际 HTTP 响应状态码,并写入 OpenAPI responses |
tags |
`list[str | Enum]` | None(无分组) |
summary |
str |
由函数名推断 | path operation 的短标题(OpenAPI summary) |
description |
str |
缺省时读取函数 docstring | path operation 的完整描述(OpenAPI description) |
response_description |
str |
"Successful Response" |
response 的描述(OpenAPI responses.<code>.description) |
deprecated |
bool |
False |
标记接口弃用(OpenAPI deprecated: true) |
总结
FastAPI 允许通过给 path operation decorator 传参,非常轻量地为接口附加丰富的配置与元数据:status_code 控制响应状态码与文档一致性;tags(含 Enum 化管理)驱动文档分组;summary / description / docstring(支持 Markdown)定义标题与详述;response_description 细化响应说明;deprecated 无痛标记退役接口。这些配置最终都汇入 OpenAPI 模式(可访问 /openapi.json 查看),使自动生成的文档、SDK 与文档界面的信息质量完全由几行装饰器参数掌控。
如果想继续深入,可以:
- 阅读本教程的英文原版与配套代码 tutorial 目录源码;
- 在本仓库运行对应回归测试,验证各参数生成的 OpenAPI 模式,测试目录为 tests/test_tutorial/test_path_operation_configurations/;
- 结合 fastapi/routing.py 中
APIRoute与add_api_route的签名理解参数流向;在搭建大型 API 项目时,还可以参考本仓库中关于 Python 类型注解、请求体与响应模型等进阶教程,把元数据配置与类型驱动的校验能力组合起来。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00




