附加状态码¶
默认情况下,FastAPI 会使用 JSONResponse
返回响应,将你在 路径操作 中返回的内容放入该 JSONResponse
中。
它会使用默认的状态码或你在 路径操作 中设置的状态码。
附加状态码¶
如果你想返回除主要状态码之外的其他状态码,你可以通过直接返回一个 Response
,比如 JSONResponse
,并直接设置附加的状态码来实现。
例如,假设你有一个 路径操作,允许更新项目,并在成功时返回 HTTP 状态码 200 "OK"。
但你还需要接受新项目。当项目之前不存在时,它会创建它们,并返回 HTTP 状态码 201 "Created"。
要实现这一点,请导入 JSONResponse
,并直接在其中返回你的内容,设置你想要的状态码:
from typing import Annotated
from fastapi import Body, FastAPI, status
from fastapi.responses import JSONResponse
app = FastAPI()
items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}}
@app.put("/items/{item_id}")
async def upsert_item(
item_id: str,
name: Annotated[str | None, Body()] = None,
size: Annotated[int | None, Body()] = None,
):
if item_id in items:
item = items[item_id]
item["name"] = name
item["size"] = size
return item
else:
item = {"name": name, "size": size}
items[item_id] = item
return JSONResponse(status_code=status.HTTP_201_CREATED, content=item)
from typing import Annotated, Union
from fastapi import Body, FastAPI, status
from fastapi.responses import JSONResponse
app = FastAPI()
items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}}
@app.put("/items/{item_id}")
async def upsert_item(
item_id: str,
name: Annotated[Union[str, None], Body()] = None,
size: Annotated[Union[int, None], Body()] = None,
):
if item_id in items:
item = items[item_id]
item["name"] = name
item["size"] = size
return item
else:
item = {"name": name, "size": size}
items[item_id] = item
return JSONResponse(status_code=status.HTTP_201_CREATED, content=item)
from typing import Union
from fastapi import Body, FastAPI, status
from fastapi.responses import JSONResponse
from typing_extensions import Annotated
app = FastAPI()
items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}}
@app.put("/items/{item_id}")
async def upsert_item(
item_id: str,
name: Annotated[Union[str, None], Body()] = None,
size: Annotated[Union[int, None], Body()] = None,
):
if item_id in items:
item = items[item_id]
item["name"] = name
item["size"] = size
return item
else:
item = {"name": name, "size": size}
items[item_id] = item
return JSONResponse(status_code=status.HTTP_201_CREATED, content=item)
Tip
如果可能,建议使用 Annotated
版本。
from fastapi import Body, FastAPI, status
from fastapi.responses import JSONResponse
app = FastAPI()
items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}}
@app.put("/items/{item_id}")
async def upsert_item(
item_id: str,
name: str | None = Body(default=None),
size: int | None = Body(default=None),
):
if item_id in items:
item = items[item_id]
item["name"] = name
item["size"] = size
return item
else:
item = {"name": name, "size": size}
items[item_id] = item
return JSONResponse(status_code=status.HTTP_201_CREATED, content=item)
Tip
如果可能,建议使用 Annotated
版本。
from typing import Union
from fastapi import Body, FastAPI, status
from fastapi.responses import JSONResponse
app = FastAPI()
items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}}
@app.put("/items/{item_id}")
async def upsert_item(
item_id: str,
name: Union[str, None] = Body(default=None),
size: Union[int, None] = Body(default=None),
):
if item_id in items:
item = items[item_id]
item["name"] = name
item["size"] = size
return item
else:
item = {"name": name, "size": size}
items[item_id] = item
return JSONResponse(status_code=status.HTTP_201_CREATED, content=item)
Warning
当你直接返回一个 Response
时,如上面的例子所示,它将直接返回。
它不会被模型序列化等。
确保它具有你希望它具有的数据,并且值是有效的 JSON(如果你使用的是 JSONResponse
)。
"技术细节"
你也可以使用 from starlette.responses import JSONResponse
。
FastAPI 提供了与 fastapi.responses
相同的 starlette.responses
,只是为了方便你,开发者。但大多数可用的响应直接来自 Starlette。与 status
相同。
OpenAPI 和 API 文档¶
如果你直接返回附加的状态码和响应,它们不会包含在 OpenAPI 模式(API 文档)中,因为 FastAPI 无法提前知道你要返回什么。
但你可以在代码中使用以下方式进行文档化:附加响应。