FastAPI 响应状态码:管理和自定义 HTTP Status Code

FastAPI 响应状态码:管理和自定义 HTTP Status Code

本文介绍了如何在 FastAPI 中声明、使用和修改 HTTP 状态码,涵盖了常见的 HTTP 状态码分类,如信息响应(1xx)、成功状态(2xx)、客户端错误(4xx)和服务器错误(5xx)。通过 status_code 参数和 fastapi.status 常量简化开发,并提供了如何根据业务需求动态调整状态码的方法。此外,还介绍了如何通过 Response 参数在路径操作函数内部修改响应状态码,以实现更精确的控制和更好的客户端交互体验。

在 FastAPI 中,正确设置和管理 HTTP 状态码对于API的准确性和响应性至关重要。以下示例中使用的 Python 版本为 Python 3.10.15,FastAPI 版本为 0.115.4

一 声明 HTTP 状态码

from fastapi import FastAPI, status

app = FastAPI()


@app.post("/items/", status_code=201)
async def create_item(name: str):
    return {"name": name}

status_code 参数属于装饰器中的参数,而非 路径操作函数 的参数。它接收一个表示 HTTP 状态码的数字,或支持 IntEnum 类型,例如 Python 的 http.HTTPStatus。运行代码文件 chapter17.py 来启动应用:

$ uvicorn chapter17:app --reload

SwaggerUI 中可以查看在线文档:http://127.0.0.1:8000/docs 。在文档中会code会有显示:
在这里插入图片描述

二 HTTP 协议状态码

在 HTTP 协议中,状态码是响应的一部分,通常由三位数字组成,并有便于识别的名称,但关键仍是数字。常用状态码如下:

  • 1xx(信息):返回信息,通常不包含响应体,使用较少。

  • 2xx

    (成功):表示请求成功,是最常用的状态码。

    • 200:成功,默认状态码,表示一切正常。
    • 201:已创建,通常在创建新资源时使用。
    • 204:无内容,表示没有响应体。
  • 3xx

    (重定向):表示重定向请求,响应不一定包含内容。

    • 304:未修改,表示资源未改变,不返回响应体。
  • 4xx

    (客户端错误):表示请求有误。

    • 400:一般客户端错误。
    • 404:未找到资源。
  • 5xx(服务器错误):表示服务器问题,通常由服务器或应用错误引发,极少直接使用。

详解见 Web HTTP Status

在这里插入图片描述

在开发应用软件时,有时会自定义非标准响应码,这些响应码与标准的 HTTP 响应码不同。

三 使用 fastapi.status 中的变量

@app.post("/items01/", status_code=status.HTTP_201_CREATED)
async def create_item(name: str):
    return {"name": name}

可以使用 fastapi.status 中预定义的变量,或通过 from starlette import status 导入。为了简化开发,FastAPI 提供了与 starlette.status 相同的 fastapi.status,该变量直接来源于 Starlette。以下是已定义的 HTTP status code 变量:

HTTP_100_CONTINUE = 100
HTTP_101_SWITCHING_PROTOCOLS = 101
HTTP_102_PROCESSING = 102
HTTP_103_EARLY_HINTS = 103
HTTP_200_OK = 200
HTTP_201_CREATED = 201
HTTP_202_ACCEPTED = 202
HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203
HTTP_204_NO_CONTENT = 204
HTTP_205_RESET_CONTENT = 205
HTTP_206_PARTIAL_CONTENT = 206
HTTP_207_MULTI_STATUS = 207
HTTP_208_ALREADY_REPORTED = 208
HTTP_226_IM_USED = 226
HTTP_300_MULTIPLE_CHOICES = 300
HTTP_301_MOVED_PERMANENTLY = 301
HTTP_302_FOUND = 302
HTTP_303_SEE_OTHER = 303
HTTP_304_NOT_MODIFIED = 304
HTTP_305_USE_PROXY = 305
HTTP_306_RESERVED = 306
HTTP_307_TEMPORARY_REDIRECT = 307
HTTP_308_PERMANENT_REDIRECT = 308
HTTP_400_BAD_REQUEST = 400
HTTP_401_UNAUTHORIZED = 401
HTTP_402_PAYMENT_REQUIRED = 402
HTTP_403_FORBIDDEN = 403
HTTP_404_NOT_FOUND = 404
HTTP_405_METHOD_NOT_ALLOWED = 405
HTTP_406_NOT_ACCEPTABLE = 406
HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407
HTTP_408_REQUEST_TIMEOUT = 408
HTTP_409_CONFLICT = 409
HTTP_410_GONE = 410
HTTP_411_LENGTH_REQUIRED = 411
HTTP_412_PRECONDITION_FAILED = 412
HTTP_413_REQUEST_ENTITY_TOO_LARGE = 413
HTTP_414_REQUEST_URI_TOO_LONG = 414
HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE = 416
HTTP_417_EXPECTATION_FAILED = 417
HTTP_418_IM_A_TEAPOT = 418
HTTP_421_MISDIRECTED_REQUEST = 421
HTTP_422_UNPROCESSABLE_ENTITY = 422
HTTP_423_LOCKED = 423
HTTP_424_FAILED_DEPENDENCY = 424
HTTP_425_TOO_EARLY = 425
HTTP_426_UPGRADE_REQUIRED = 426
HTTP_428_PRECONDITION_REQUIRED = 428
HTTP_429_TOO_MANY_REQUESTS = 429
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS = 451
HTTP_500_INTERNAL_SERVER_ERROR = 500
HTTP_501_NOT_IMPLEMENTED = 501
HTTP_502_BAD_GATEWAY = 502
HTTP_503_SERVICE_UNAVAILABLE = 503
HTTP_504_GATEWAY_TIMEOUT = 504
HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505
HTTP_506_VARIANT_ALSO_NEGOTIATES = 506
HTTP_507_INSUFFICIENT_STORAGE = 507
HTTP_508_LOOP_DETECTED = 508
HTTP_510_NOT_EXTENDED = 510
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED = 511

四 使用 Response 参数更改状态码

@app.put("/get-or-create-task/{task_id}", status_code=200)
def get_or_create_task(task_id: str, response: Response):
    if task_id not in tasks:
        tasks[task_id] = "This didn't exist before"
        response.status_code = status.HTTP_201_CREATED
    return tasks[task_id]

路径操作函数中声明一个 Response 类型的参数,根据业务逻辑修改状态码 response.status_code = status.HTTP_201_CREATED

五 完整代码示例

from fastapi import FastAPI, status, Response

app = FastAPI()


@app.post("/items/", status_code=201)
async def create_item(name: str):
    return {"name": name}


@app.post("/items01/", status_code=status.HTTP_201_CREATED)
async def create_item(name: str):
    return {"name": name}


tasks = {"foo": "Listen to the Bar Fighters"}


@app.put("/get-or-create-task/{task_id}", status_code=200)
def get_or_create_task(task_id: str, response: Response):
    if task_id not in tasks:
        tasks[task_id] = "This didn't exist before"
        response.status_code = status.HTTP_201_CREATED
    return tasks[task_id]
  

六 源码地址

详情见:GitHub FastApiProj

七 参考

[1] FastAPI 文档

FastAPI 中返回特定状态码响应数据可以通过多种方式实现,包括使用 `status_code` 参数、`fastapi.status` 模块中的常量以及直接操作响应对象。以下是一些常见的方法: ### 使用 `status_code` 参数 可以在路径操作装饰器中通过 `status_code` 参数指定默认返回的状态码。例如,设置一个返回 201 Created 状态码的接口: ```python from fastapi import FastAPI, status app = FastAPI() @app.post("/items/", status_code=status.HTTP_201_CREATED) def create_item(): return {"message": "Item created successfully"} ``` 此方法适用于需要为整个端点设定固定状态码的情况[^1]。 ### 在函数内部动态修改状态码 如果需要根据业务逻辑动态决定返回的状态码,则可以直接在路径操作函数中使用 `Response` 对象来更改状态码: ```python from fastapi import FastAPI, Response app = FastAPI() @app.get("/dynamic-status") def dynamic_status(response: Response): # 根据某些条件判断 condition = True if condition: response.status_code = 200 return {"message": "Condition met"} else: response.status_code = 404 return {"error": "Condition not met"} ``` 这种方式提供了更大的灵活性,可以根据不同的业务场景返回相应的状态码[^1]。 ### 自定义响应类 对于更复杂的响应需求,可以继承 `fastapi.responses.Response` 类来自定义响应行为。例如,创建一个返回纯文本的响应类: ```python from fastapi import FastAPI from fastapi.responses import Response class CustomTextResponse(Response): media_type = "text/plain" app = FastAPI() @app.get("/", response_class=CustomTextResponse) def main(): return "Hello World" ``` 这允许开发者对响应的内容类型其他特性进行细粒度控制[^2]。 ### 结合使用 JSON 响应状态码 通常情况下,除了状态码外还需要返回一些结构化的数据。FastAPI 的 `JSONResponse` 可以很好地满足这一需求: ```python from fastapi import FastAPI from fastapi.responses import JSONResponse from fastapi import status app = FastAPI() @app.get("/json-response") def json_response(): content = {"error": "Not found"} return JSONResponse(content=content, status_code=status.HTTP_404_NOT_FOUND) ``` 这种方法不仅能够发送自定义状态码,还能同时传递详细的错误信息或其他数据给客户端[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲代码不忘补水

感谢有你,让我的创作更有价值!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值