当你创建一个 FastAPI 路径操作 时,你可以正常返回以下任意一种数据:dict
,list
,Pydantic 模型,数据库模型等等。
FastAPI 默认会使用 jsonable_encoder
将这些类型的返回值转换成 JSON 格式,
默认情况下会以content-type: application/json
格式返回
在有些情况下,我们需要在路径操作中直接返回Response对象,这样我们能有更多的操作灵活性,比如自定义头headers 信息、自定义Cookie信息等
默认返回 json 格式
返回一个基本数据类型 dict,list,str 会以 json 格式返回
from fastapi import FastAPI
import uvicorn
app = FastAPI()
@app.get('/demo')
def demo():
item = {
"name": "yoyo",
"email": "[email protected]"
}
return item
get 请求访问 http://127.0.0.1:8000/demo
HTTP/1.1 200 OK
date: Tue, 18 Jul 2023 10:50:41 GMT
server: uvicorn
content-length: 36
content-type: application/json
{"name":"yoyo","email":"[email protected]"}
JSONResponse 自定义返回
可以使用 from starlette.responses import JSONResponse
定制返回内容,包含响应状态码,响应headers 和 响应body
JSONResponse 继承自 Response 类,部分源码如下:
class JSONResponse(Response):
media_type = "application/json"
def __init__(
self,
content: typing.Any,
status_code: int = 200,
headers: typing.Optional[typing.Dict[str, str]] = None,
media_type: typing.Optional[str] = None,
background: typing.Optional[BackgroundTask] = None,
) -> None:
super().__init__(content, status_code, headers, media_type, background)
JSONResponse可传参数:
- content: 响应body内容,
str
或者bytes
. - status_code: 响应状态码,int类型,默认200.
- headers: 响应头部,dict类型.
- media_type:media type. 例如
"text/html"
. - background:后台任务
自定义 JSONResponse 响应, status_code 可以自定义状态码.
FastAPI 会自动包含 Content-Length
,以及Content-Type,charset
等头信息。
from fastapi import FastAPI, status
from fastapi.responses import JSONResponse
import uvicorn
app = FastAPI()
@app.get('/demo')
def demo():
item = {
"name": "yoyo",
"email": "[email protected]"
}
return JSONResponse(
content=item, status_code=status.HTTP_201_CREATED
)
get 请求访问http://127.0.0.1:8000/demo
HTTP/1.1 201 Created
date: Tue, 18 Jul 2023 10:59:53 GMT
server: uvicorn
content-length: 36
content-type: application/json
{"name":"yoyo","email":"[email protected]"}
于是可以看到响应状态码变成了 201 。
自定义返回 headers 和 media_type
响应头部添加 headers 内容和设置 media_type 响应 body 媒体类型
from starlette.responses import JSONResponse
@app.get('/resp/demo')
async def resp_demo():
return JSONResponse(
'hello world',
status_code=201,
headers={"x-token": "aa11233"},
media_type="text/html"
)