Is there a way to pretty print / prettify a JSON response in FastAPI?

Question:

I’m looking for something that is similar to Flask’s app.config['JSONIFY_PRETTYPRINT_REGULAR'] = True.

Asked By: New Coder

||

Answers:

I’m not sure what exactly your problem is, can you tell what the background of your need?

however, because FASTAPI is based on open standards(OpenAPI, JSONSchema) it has automatic docs. –>
FastAPI Auto Docs.

you have the Swagger UI under host/docs.
or the ReDoc under host/redoc.
Both will give you pretty representation of the JSON response in ease.

Answered By: IlayG01

This is taken from David Montague.

You can annotate any endpoint with a custom response class, for example

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

An example for PrettyJSONResponse could be (indent=4 is what you were asking)

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")
Answered By: Wolfgang Kuehn

In order to avoid blocking the event loop for large lists of models, I ended up with a solution like the one below.

This should:

  1. Not block the event loop
  2. Stream results (much faster)
  3. Release event loop in between model dict actions
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)
Answered By: Eric Longstreet
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.