此问题已在此处有答案:
How to return data in JSON format using FastAPI?(1个答案)
20小时前关闭。
我正在探索FastAPI,并在Windows上的Docker桌面上运行它。下面是我在Docker中成功部署的main.py
:
#main.py
import fastapi
import json
from fastapi.responses import JSONResponse
app = fastapi.FastAPI()
@app.get('/api/get_weights1')
async def get_weights1():
weights = {'aa': 10, 'bb': 20}
return json.dumps(weights)
@app.get('/api/get_weights2')
async def get_weights2():
weights = {'aa': 10, 'bb': 20}
return JSONResponse(content=weights, status_code=200)
我有一个简单的python文件get_weights.py
来向这两个API发出请求:
#get_weights.py
import requests
import json
resp = requests.get('http://127.0.0.1:8000/api/get_weights1')
print('ok', resp.status_code)
if resp.status_code == 200:
print(resp.json())
resp = requests.get('http://127.0.0.1:8000/api/get_weights2')
print('ok', resp.status_code)
if resp.status_code == 200:
print(resp.json())
我从两个API得到相同的响应,输出:
ok 200
{"aa": 10, "bb": 20}
ok 200
{'aa': 10, 'bb': 20}
无论我使用json.dumps()
还是JSONResponse()
,响应似乎都是一样的。我已经阅读了FastAPI documentation on JSONResponse,但我仍然有以下问题:
请问这两种方法有什么不同吗?
如果存在差异,建议使用哪种方法(为什么?)?
2条答案
按热度按时间0s7z1bwu1#
在FastAPI中,你可以用3种不同的方式创建响应(从最简洁到最灵活):
1
在docs you linked中,我们可以看到FastAPI会自动将这个
dict
字符串化,并将其 Package 在JSONResponse
中。这种方式最简洁,涵盖了大多数用例。二
但是有时候你需要返回自定义头(例如
REMOTE-USER=username
)或不同的状态码(可能是201 - Created或202 - Accepted)。这种情况下你需要使用JSONResponse
。问题是,现在如果我们没有简单的dict,我们必须使用
jsonable_encoder(some_model) # -> dict
来获取它。所以它有点冗长。对于可用的选项,请查看Starlette文档,因为FastAPI只是重新导出它。更复杂的例子:
三
最后,你不需要返回json -你也可以返回csv,html或任何其他类型的文件。这种情况下,我们必须使用
Response
并指定media_type
。同样使用Starlette docs。总之
请注意,Fastapi文档指出:
当您直接返回响应时,其数据不会被验证、转换(序列化),也不会自动记录。
我们来看看有什么不同:第一个方法与其他FastAPI功能集成良好,因此应该始终是首选。只有当您需要提供自定义头或状态码时才使用第二个选项。最后,只有当您希望返回非json的内容时才使用第三个选项。
mwg9r5ms2#
我尝试了一些变化,发现以下...
(1)这两种方法都不能序列化datetime对象。例如,如果权重为:
那么这两个方法将具有相同的返回状态和错误:
500内部服务器错误
TypeError:date类型的对象不是JSON可序列化的
为了克服这种使用
和
(2)我还尝试了按原样返回普通的
dict
,特别是如果其中有一个datetime对象。正如@Matija所提到的,FastAPI会自动将这个dict
字符串化并将其 Package 在响应中。例如:输出:
(3)正如@Matija所提到的,
JSONResponse()
方法允许自定义返回的响应。例如,响应状态可以自定义为201(而不是200)。还可以返回不同类型的对象。这可能是使用此方法优于json.dumps()
方法的优点。例如:与之前的输出相同: