在FastAPI中有一种方法可以美化JSON响应吗?

6

我正在寻找类似于 Flask 的 app.config['JSONIFY_PRETTYPRINT_REGULAR'] = True 的东西。

3个回答

13

以下内容摘自David Montague

您可以使用自定义响应类注释任何端点,例如:

@app.get("/config", response_class=PrettyJSONResponse)
def get_config() -> MyConfigClass:
    return app.state.config

PrettyJSONResponse 的一个示例可以是(indent=4 是您所要求的)

import json, typing
from starlette.responses import Response

class PrettyJSONResponse(Response):
    media_type = "application/json"

    def render(self, content: typing.Any) -> bytes:
        return json.dumps(
            content,
            ensure_ascii=False,
            allow_nan=False,
            indent=4,
            separators=(", ", ": "),
        ).encode("utf-8")

4
请注意,PrettyJSONResponse 在处理大数据集时会阻塞异步函数,因此需要谨慎使用,否则在某些情况下会导致性能问题。 - Eric Longstreet
@EricLongstreet 很棒的发现。怎样修复它呢?仅仅在def render()中添加async是行不通的。Mypy对此会有意见的。 - DataMinion
1
@BrandonStivers,添加了一个答案示例。 - Eric Longstreet

2
为了避免在大型模型列表中阻塞事件循环,我最终采用了以下解决方案。
这个方案应该能够:
  1. 不会阻塞事件循环
  2. 流式传输结果(速度更快)
  3. 在模型字典操作之间释放事件循环
async def streaming_output_json(content: List[BaseModel]) -> StreamingResponse:
    """
    Convert a list of Pydantic models to a JSON StreamingResponse.
    """
    async def jsonify_async(models: List[BaseModel]) -> AsyncIterable[str]:
        yield '['
        for i, model in enumerate(models):
            await asyncio.sleep(0)
            if i > 0:
                yield ','
            result_dict = jsonable_encoder(model)
            serialized_dict = json.dumps(result_dict)
            yield serialized_dict
        yield ']'

    return StreamingResponse(jsonify_async(models=content), media_type='application/json')

@router.get("")
async def get_huge_result():
    results = [model1, model2, ...]
    return await streaming_output_json(results)

感谢提供的示例。我正在开发一个 FastAPI 版本的 httpbin(带有一些额外的功能),这将非常有用。希望我能够将其适应为 ORJSONResponse。只需将输出扔到 ORJSONResponse(streaming_output_json(results)) 中即可工作。希望 ORJSONResponse 不会将其重新格式化为单行。哈哈 - DataMinion
2
请记住,如果orjsonresponse不是异步的,您将遇到相同的问题。如果您想使用它,在for循环中最好将其替换掉。 - Eric Longstreet
1
研究FastAPI的源代码(https://github.com/tiangolo/fastapi/blob/d666ccb62216e45ca78643b52c235ba0d2c53986/fastapi/responses.py#L29),看起来底层的orjson调用不是异步的(与其它大部分代码不同)。然而,orjson比常规json快5到6倍,因此我认为在给定的开发环境中使用它时不会成为瓶颈。 - DataMinion

-3

我不确定你的问题具体是什么,你能告诉我你需要的背景吗?

然而,由于FASTAPI基于开放标准(OpenAPI,JSONSchema),它具有自动文档。--> FastAPI自动文档

你可以在host/docs下找到Swagger UI, 或者在host/redoc下找到ReDoc两者都会以简单易懂的方式呈现JSON响应的漂亮表示。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接