FastAPI 状态码模块 status 完全指南:从 HTTP/WebSocket 常量到路由状态码声明
fastapi.status 是 FastAPI 提供的状态码常量集合,它把易写错、难记忆的整数状态码封装成语义化的命名常量(如 HTTP_201_CREATED、HTTP_403_FORBIDDEN),可配合编辑器自动补全在路由装饰器、HTTPException 等场景中安全使用。本文以仓库内的 状态码参考文档 为主线,结合 fastapi/init.py、路由源码 与官方教程 response-status-code,系统讲解该模块的来历、全部常量、典型用法与底层实现原理,帮助你彻底告别"死记硬背状态码数字"。
什么是 fastapi.status,它从哪来
参考文档开篇即点明核心事实:status 模块可以直接从 FastAPI 导入:
from fastapi import status
但它的"真身"并不在 FastAPI 自己的代码里,而是直接由 Starlette 提供。在仓库源码中可以看到确切的转发逻辑,见 fastapi/init.py:
from starlette import status as status
也就是说,下面两种写法完全等价:
from fastapi import status
from starlette import status
FastAPI 之所以在顶层重新暴露 fastapi.status,纯粹是为开发者提供一处便捷统一的导入入口——你在写 from fastapi import FastAPI 的同时,就可以顺带把 status 一起引入,无需关心 Starlette 的内部布局。而 status 模块内部存放的,是一组用整数状态码命名的常量(variables),例如:
| 状态码 | 常量名 |
|---|---|
| 200 | status.HTTP_200_OK |
| 201 | status.HTTP_201_CREATED |
| 403 | status.HTTP_403_FORBIDDEN |
| 404 | status.HTTP_404_NOT_FOUND |
| 418 | status.HTTP_418_IM_A_TEAPOT |
| 500 | status.HTTP_500_INTERNAL_SERVER_ERROR |
命名的规律是 HTTP_ + 三位状态码数字 + 下划线 + 大写语义名称,常量名本身就携带了数字信息,因此看到名字即可推断数值,反过来也无需背下"403 到底是哪个数字"。
模块里到底有哪些常量:HTTP 与 WebSocket 全覆盖
参考文档用 ::: fastapi.status 指令在 API 参考页自动展开该模块的全部成员。基于当前仓库环境实际导入的 Starlette status 模块,这些常量按语义可分为 HTTP 状态码 与 WebSocket 关闭码 两大类,覆盖 1xx 到 5xx 的所有标准区间:
1xx 信息类(响应不能携带响应体)
HTTP_100_CONTINUE、HTTP_101_SWITCHING_PROTOCOLS、HTTP_102_PROCESSING、HTTP_103_EARLY_HINTS
2xx 成功类(日常使用最频繁)
HTTP_200_OK(默认值)、HTTP_201_CREATED(创建成功)、HTTP_202_ACCEPTED、HTTP_203_NON_AUTHORITATIVE_INFORMATION、HTTP_204_NO_CONTENT(无响应体)、HTTP_205_RESET_CONTENT、HTTP_206_PARTIAL_CONTENT、HTTP_207_MULTI_STATUS、HTTP_208_ALREADY_REPORTED、HTTP_226_IM_USED
3xx 重定向类
HTTP_300_MULTIPLE_CHOICES、HTTP_301_MOVED_PERMANENTLY、HTTP_302_FOUND、HTTP_303_SEE_OTHER、HTTP_304_NOT_MODIFIED(不可有响应体)、HTTP_305_USE_PROXY、HTTP_306_RESERVED、HTTP_307_TEMPORARY_REDIRECT、HTTP_308_PERMANENT_REDIRECT
4xx 客户端错误类(日常使用第二频繁)
HTTP_400_BAD_REQUEST、HTTP_401_UNAUTHORIZED、HTTP_402_PAYMENT_REQUIRED、HTTP_403_FORBIDDEN、HTTP_404_NOT_FOUND、HTTP_405_METHOD_NOT_ALLOWED、HTTP_406_NOT_ACCEPTABLE、HTTP_407_PROXY_AUTHENTICATION_REQUIRED、HTTP_408_REQUEST_TIMEOUT、HTTP_409_CONFLICT、HTTP_410_GONE、HTTP_411_LENGTH_REQUIRED、HTTP_412_PRECONDITION_FAILED、HTTP_413_REQUEST_ENTITY_TOO_LARGE、HTTP_414_REQUEST_URI_TOO_LONG、HTTP_415_UNSUPPORTED_MEDIA_TYPE、HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE、HTTP_417_EXPECTATION_FAILED、HTTP_418_IM_A_TEAPOT、HTTP_421_MISDIRECTED_REQUEST、HTTP_422_UNPROCESSABLE_ENTITY、HTTP_423_LOCKED、HTTP_424_FAILED_DEPENDENCY、HTTP_425_TOO_EARLY、HTTP_426_UPGRADE_REQUIRED、HTTP_428_PRECONDITION_REQUIRED、HTTP_429_TOO_MANY_REQUESTS、HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE、HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS
5xx 服务器错误类(一般由框架/服务器自动产生,很少手写)
HTTP_500_INTERNAL_SERVER_ERROR、HTTP_501_NOT_IMPLEMENTED、HTTP_502_BAD_GATEWAY、HTTP_503_SERVICE_UNAVAILABLE、HTTP_504_GATEWAY_TIMEOUT、HTTP_505_HTTP_VERSION_NOT_SUPPORTED、HTTP_506_VARIANT_ALSO_NEGOTIATES、HTTP_507_INSUFFICIENT_STORAGE、HTTP_508_LOOP_DETECTED、HTTP_510_NOT_EXTENDED、HTTP_511_NETWORK_AUTHENTICATION_REQUIRED
WebSocket 关闭码(以 WS_ 为前缀)
WS_1000_NORMAL_CLOSURE、WS_1001_GOING_AWAY、WS_1002_PROTOCOL_ERROR、WS_1003_UNSUPPORTED_DATA、WS_1005_NO_STATUS_RCVD、WS_1006_ABNORMAL_CLOSURE、WS_1007_INVALID_FRAME_PAYLOAD_DATA、WS_1008_POLICY_VIOLATION、WS_1009_MESSAGE_TOO_BIG、WS_1010_MANDATORY_EXT、WS_1011_INTERNAL_ERROR、WS_1012_SERVICE_RESTART、WS_1013_TRY_AGAIN_LATER、WS_1014_BAD_GATEWAY、WS_1015_TLS_HANDSHAKE
说明:以上为当前仓库环境内实际安装的 Starlette
status模块可导入的完整常量集合。status由 Starlette 版本决定,若你的环境版本不同,成员可能略有增减。
核心场景一:在路由装饰器中声明响应状态码
状态码最典型的用法是作为 path operation 装饰器(@app.get()、@app.post()、@app.put()、@app.delete() 等)的 status_code 参数传入。参考文档给出的示例在仓库的 docs_src/response_status_code/tutorial001_py310.py 有完整对应:
from fastapi import FastAPI, status
app = FastAPI()
@app.get("/items/", status_code=status.HTTP_418_IM_A_TEAPOT)
def read_items():
return [{"name": "Plumbus"}, {"name": "Portal Gun"}]
HTTP_418_IM_A_TEAPOT 即 "我是一个茶壶"(418 I'm a teapot),是一个常用于演示的娱乐性状态码,其数字为 418。声明 status_code 后会发生两件事:
- 实际响应携带该状态码——框架返回响应时会把它写入 HTTP 状态行;
- 该状态码被写进 OpenAPI 模式——因此在
/docs(Swagger UI)等接口文档界面中会被正确标注为该接口的响应状态码,前端与代码生成工具都能据此感知。
两个需要区分清楚的参数位置
值得强调(参考文档也专门以 note 提示):status_code 是 装饰器方法(get/post/...)的参数,而不是你的 path operation 函数 的参数。它和 Query、Body、路径参数等"函数参数"处于完全不同的层级,不要把它们混淆。
另外,status_code 除了接收纯整数,也可以接收 IntEnum,例如 Python 标准库的 http.HTTPStatus:
import http
from fastapi import FastAPI
app = FastAPI()
@app.get("/health/", status_code=http.HTTPStatus.OK)
def health():
return {"status": "ok"}
源码层面:状态码如何被处理
在 fastapi/routing.py 中可以看到,路由注册时会先把 IntEnum 统一转成普通整数,再存入路由对象:
if isinstance(status_code, IntEnum):
status_code = int(status_code)
route.status_code = status_code
这正是上面 http.HTTPStatus.OK 这类枚举能直接工作的原因。而在响应阶段,框架会根据结果判断当前实际状态码并组装 response_args,见 fastapi/routing.py 附近的逻辑。
"无响应体"状态码的自动识别
参考文档特别指出:某些状态码本身不允许携带响应体(如 204 No Content、304 Not Modified),FastAPI 对此是"知情"的。这同样能从源码得到印证——fastapi/routing.py 在序列化响应时会调用 is_body_allowed_for_status_code 判断当前状态码是否允许响应体;在自动生成额外的响应模型、响应字段时也会对这类状态码做断言保护,见 fastapi/routing.py 与 fastapi/routing.py,异常时会抛出诸如 Status code 204 must not have a response body 的明确提示。因此使用常量声明状态码,还能在开发期就规避"给无响应体状态码配了 body"这类隐蔽错误。
核心场景二:在 HTTPException 中抛出错误状态码
除装饰器外,status 常量最常见的落地场景是与 HTTPException 配合抛出错误响应。以仓库 fastapi/exceptions.py 中展示的典型模式为例:
from fastapi import FastAPI, HTTPException, status
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: str):
if item_id not in DB:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Item not found")
return {"item_id": item_id}
这里的 HTTPException 构造函数接收 status_code 与 detail 等参数,将 status.HTTP_404_NOT_FOUND(数字 404)作为响应的状态码、"Item not found" 作为错误详情返回给客户端。相比直接写 404,常量的语义一目了然,代码评审与协作时不易产生歧义。
提示:若业务上需要返回"跟默认声明不同的"状态码,参考官方进阶教程 Advanced User Guide: Response Change Status Code,可在路径操作函数中直接返回带
status_code的Response对象来覆盖装饰器里的默认值。
教程对照:200/201 的实操演练
主教程 Response Status Code 给出了另一个贴近真实业务(建表后返回 201)的完整示例,仓库中的可运行源码在 docs_src/response_status_code/tutorial002_py310.py:
from fastapi import FastAPI, status
app = FastAPI()
@app.post("/items/", status_code=status.HTTP_201_CREATED)
async def create_item(name: str):
return {"name": name}
对照 HTTP 语义:
200是默认状态码,表示"一切 OK";201 Created常用于在数据库中新创建了一条记录之后的响应——上述POST /items/创建条目并返回201即是标准 REST 实践;204 No Content是特殊情形:客户端不需要任何返回内容,响应体必须为空。
若不想依赖这些常量,status_code=201 也能工作,因为两者数值完全一致——常量只是"带名字的数字"。关键收益正如参考文档所说:编辑器补全让你输入 status.HTTP_201_ 前缀后直接看到候选,不必再去搜索引擎确认"创建成功是 200 还是 201"。
状态码区间速查与使用取舍
教程把五类状态码的取舍总结得很清楚,这里结合实战给出速查:
| 区间 | 含义 | 使用建议 |
|---|---|---|
100 – 199 |
Information 信息类 | 极少直接使用;此类响应不允许有响应体 |
200 – 299 |
Successful 成功类 | 使用最多;200 为默认,201 建表后返回,204 无内容返回且无响应体 |
300 – 399 |
Redirection 重定向 | 视情况使用;其中 304 Not Modified 不允许有响应体 |
400 – 499 |
Client error 客户端错误 | 第二常用;404 表示资源未找到,通用客户端错误直接给 400 |
500 – 599 |
Server error 服务器错误 | 几乎不手写;应用代码或服务器异常时会由框架/服务器自动返回 |
进一步理解各状态码的确切语义,可参考 Mozilla 开发者网络(MDN)对 HTTP 状态码的官方说明;而在 FastAPI 语境下,"该用哪个数、对应哪个常量"直接查阅上文完整列表即可。
小结:何时该用 fastapi.status
建议在所有需要书写状态码的地方都优先使用 fastapi.status 常量,包括但不限于:
- 路由装饰器的
status_code=参数; HTTPException(status_code=...)抛错;- 直接构造
Response/JSONResponse等响应对象时; - WebSocket 关闭操作中引用
WS_*关闭码。
它们与硬编码整数完全等价,但换来的是更强的可读性、编辑器自动补全与更低的人为笔误风险。想继续深挖的读者,可以对照阅读仓库内三处资料:API 参考入口 status.md、主教程 response-status-code.md 及其可运行示例 tutorial001_py310.py / tutorial002_py310.py。
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 StartedRust0624
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