首页
/ FastAPI 状态码模块 status 完全指南:从 HTTP/WebSocket 常量到路由状态码声明

FastAPI 状态码模块 status 完全指南:从 HTTP/WebSocket 常量到路由状态码声明

2026-09-06 18:03:24作者:卓艾滢Kingsley

fastapi.status 是 FastAPI 提供的状态码常量集合,它把易写错、难记忆的整数状态码封装成语义化的命名常量(如 HTTP_201_CREATEDHTTP_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_CONTINUEHTTP_101_SWITCHING_PROTOCOLSHTTP_102_PROCESSINGHTTP_103_EARLY_HINTS

2xx 成功类(日常使用最频繁) HTTP_200_OK(默认值)、HTTP_201_CREATED(创建成功)、HTTP_202_ACCEPTEDHTTP_203_NON_AUTHORITATIVE_INFORMATIONHTTP_204_NO_CONTENT(无响应体)、HTTP_205_RESET_CONTENTHTTP_206_PARTIAL_CONTENTHTTP_207_MULTI_STATUSHTTP_208_ALREADY_REPORTEDHTTP_226_IM_USED

3xx 重定向类 HTTP_300_MULTIPLE_CHOICESHTTP_301_MOVED_PERMANENTLYHTTP_302_FOUNDHTTP_303_SEE_OTHERHTTP_304_NOT_MODIFIED(不可有响应体)、HTTP_305_USE_PROXYHTTP_306_RESERVEDHTTP_307_TEMPORARY_REDIRECTHTTP_308_PERMANENT_REDIRECT

4xx 客户端错误类(日常使用第二频繁) HTTP_400_BAD_REQUESTHTTP_401_UNAUTHORIZEDHTTP_402_PAYMENT_REQUIREDHTTP_403_FORBIDDENHTTP_404_NOT_FOUNDHTTP_405_METHOD_NOT_ALLOWEDHTTP_406_NOT_ACCEPTABLEHTTP_407_PROXY_AUTHENTICATION_REQUIREDHTTP_408_REQUEST_TIMEOUTHTTP_409_CONFLICTHTTP_410_GONEHTTP_411_LENGTH_REQUIREDHTTP_412_PRECONDITION_FAILEDHTTP_413_REQUEST_ENTITY_TOO_LARGEHTTP_414_REQUEST_URI_TOO_LONGHTTP_415_UNSUPPORTED_MEDIA_TYPEHTTP_416_REQUESTED_RANGE_NOT_SATISFIABLEHTTP_417_EXPECTATION_FAILEDHTTP_418_IM_A_TEAPOTHTTP_421_MISDIRECTED_REQUESTHTTP_422_UNPROCESSABLE_ENTITYHTTP_423_LOCKEDHTTP_424_FAILED_DEPENDENCYHTTP_425_TOO_EARLYHTTP_426_UPGRADE_REQUIREDHTTP_428_PRECONDITION_REQUIREDHTTP_429_TOO_MANY_REQUESTSHTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGEHTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS

5xx 服务器错误类(一般由框架/服务器自动产生,很少手写) HTTP_500_INTERNAL_SERVER_ERRORHTTP_501_NOT_IMPLEMENTEDHTTP_502_BAD_GATEWAYHTTP_503_SERVICE_UNAVAILABLEHTTP_504_GATEWAY_TIMEOUTHTTP_505_HTTP_VERSION_NOT_SUPPORTEDHTTP_506_VARIANT_ALSO_NEGOTIATESHTTP_507_INSUFFICIENT_STORAGEHTTP_508_LOOP_DETECTEDHTTP_510_NOT_EXTENDEDHTTP_511_NETWORK_AUTHENTICATION_REQUIRED

WebSocket 关闭码(以 WS_ 为前缀) WS_1000_NORMAL_CLOSUREWS_1001_GOING_AWAYWS_1002_PROTOCOL_ERRORWS_1003_UNSUPPORTED_DATAWS_1005_NO_STATUS_RCVDWS_1006_ABNORMAL_CLOSUREWS_1007_INVALID_FRAME_PAYLOAD_DATAWS_1008_POLICY_VIOLATIONWS_1009_MESSAGE_TOO_BIGWS_1010_MANDATORY_EXTWS_1011_INTERNAL_ERRORWS_1012_SERVICE_RESTARTWS_1013_TRY_AGAIN_LATERWS_1014_BAD_GATEWAYWS_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 后会发生两件事:

  1. 实际响应携带该状态码——框架返回响应时会把它写入 HTTP 状态行;
  2. 该状态码被写进 OpenAPI 模式——因此在 /docs(Swagger UI)等接口文档界面中会被正确标注为该接口的响应状态码,前端与代码生成工具都能据此感知。

两个需要区分清楚的参数位置

值得强调(参考文档也专门以 note 提示):status_code装饰器方法(get/post/...)的参数,而不是你的 path operation 函数 的参数。它和 QueryBody、路径参数等"函数参数"处于完全不同的层级,不要把它们混淆。

另外,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 Content304 Not Modified),FastAPI 对此是"知情"的。这同样能从源码得到印证——fastapi/routing.py 在序列化响应时会调用 is_body_allowed_for_status_code 判断当前状态码是否允许响应体;在自动生成额外的响应模型、响应字段时也会对这类状态码做断言保护,见 fastapi/routing.pyfastapi/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_codedetail 等参数,将 status.HTTP_404_NOT_FOUND(数字 404)作为响应的状态码、"Item not found" 作为错误详情返回给客户端。相比直接写 404,常量的语义一目了然,代码评审与协作时不易产生歧义。

提示:若业务上需要返回"跟默认声明不同的"状态码,参考官方进阶教程 Advanced User Guide: Response Change Status Code,可在路径操作函数中直接返回带 status_codeResponse 对象来覆盖装饰器里的默认值。

教程对照: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 常量,包括但不限于:

  1. 路由装饰器的 status_code= 参数;
  2. HTTPException(status_code=...) 抛错;
  3. 直接构造 Response / JSONResponse 等响应对象时;
  4. WebSocket 关闭操作中引用 WS_* 关闭码。

它们与硬编码整数完全等价,但换来的是更强的可读性、编辑器自动补全与更低的人为笔误风险。想继续深挖的读者,可以对照阅读仓库内三处资料:API 参考入口 status.md、主教程 response-status-code.md 及其可运行示例 tutorial001_py310.py / tutorial002_py310.py

登录后查看全文
热门项目推荐
相关项目推荐