python 如何使用FastAPI返回单独的JSON响应?

kokeuurv  于 2023-04-28  发布在  Python
关注(0)|答案(1)|浏览(150)

我不确定这是否是OpenAPI标准的一部分。我试图开发一个API服务器,以取代现有的一个,这是不是开源和供应商已经走了。我面临的一个特殊挑战是它返回多个JSON对象**,而没有将它们封闭**在listarray中。例如,它在单独的行中返回以下3个JSON对象:

{"items": 10}
{"order": "shelf", "amount": 100}
{"id": 100, "date": "2022-01-01", "status": "X"}

不是list``()或数组[]

例如,下面的代码返回数组中的所有3个对象:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    data_1 = {"items": 10}
    data_2 = {"order": "shelf", "amount": 100}
    data_3 = {"id": 100, "date": "2022-01-01", "status": "X"}
    return data_1, data_2, data_3

有人能帮我用FastAPI完成这个吗?

avkwfej4

avkwfej41#

选项一

您可以直接返回一个自定义的Response,如this answer以及this answer的选项2所示。

示例
from fastapi import FastAPI, Response
import json

app = FastAPI()

def to_json(d):
    return json.dumps(d, default=str)
    
  
@app.get('/')
async def main():
    data_1 = {'items': 10}
    data_2 = {'order': 'shelf', 'amount': 100}
    data_3 = {'id': 100, 'date': '2022-01-01', 'status': 'X'}
    json_str = '\n'.join([to_json(data_1), to_json(data_2), to_json(data_3)])
    return Response(json_str, media_type='application/json')

选项二

您可以使用StreamingResponse,如herehere所示。您可能也会发现thisthis很有帮助。如果generator函数执行了一些阻塞操作,从而阻塞事件循环,那么你可以在下面定义gen()函数,而不是async def,FastAPI将使用iterate_in_threadpool()在一个单独的线程中运行generator,然后await被编辑。查看上面的链接答案以了解更多详细信息。

示例
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import json

app = FastAPI()

@app.get('/')
async def main():
    data_1 = {'items': 10}
    data_2 = {'order': 'shelf', 'amount': 100}
    data_3 = {'id': 100, 'date': '2022-01-01', 'status': 'X'}
    
    async def gen():
        for d in [data_1, data_2, data_3]:
            yield json.dumps(d, default=str) + '\n'

    return StreamingResponse(gen(), media_type='application/json')

选项三

如上面的注解部分所述,还可以返回dict(JSON)对象的字典。然而,使用此解决方案,在对象之间添加换行符将是不可行的。

示例
from fastapi import FastAPI, Response

app = FastAPI()

@app.get('/')
async def main():
    data_1 = {'items': 10}
    data_2 = {'order': 'shelf', 'amount': 100}
    data_3 = {'id': 100, 'date': '2022-01-01', 'status': 'X'}
    return {1: data_1, 2: data_2, 3: data_3}

注意事项

尽管在选项1和2中,media_type被设置为application/json,但返回的对象将不是有效的JSON,因为JSON字符串允许真实的的换行符(只允许转义的换行符,即即\\n)-也参见this answer。因此,在/docs的Swagger UI autodocs中,您在测试端点时可能会遇到以下消息:can't parse JSON. Raw result:。如果你不想得到这个消息,你可以将media_type设置为text/plain

相关问题