FastAPI: how to read body as any valid json?

ID : 131327

viewed : 6

Tags : jsonfastapipydanticjson

Top 5 Answer for FastAPI: how to read body as any valid json?

vote vote

94

You can find nearly everything inside the Request object

You are able to get request body with request.json(), which will give you the parsed JSON as dictionary.

from fastapi import Request, FastAPI  @app.post("/dummypath") async def get_body(request: Request):     return await request.json() 

If you want access the body as string, you can use request.body()

vote vote

83

The accepted answer is valid as well, but FastAPI provides a built-in way to do that - check the Singular values in body section in docs.

A parameter with the default Body gets all the payload that doesn't match passed Pydantic-typed parameters (the whole payload in our case) and converts it to the dict. In case of invalid JSON, a standard validation error would be produced.

from fastapi import Body, FastAPI  app = FastAPI()   @app.post('/test') async def update_item(         payload: dict = Body(...) ):     return payload 

UPD: Note on ... (Ellipsis) - it allows marking a value as required. Read more in the Required with Ellipsis docs section

vote vote

79

If you are confident that the incoming data is "a valid JSON", you can create a simple type annotation structure to receive the arbitrary JSON data.

from fastapi import FastAPI from typing import Any, Dict, AnyStr, List, Union  app = FastAPI()  JSONObject = Dict[AnyStr, Any] JSONArray = List[Any] JSONStructure = Union[JSONArray, JSONObject]   @app.post("/") async def root(arbitrary_json: JSONStructure = None):     return {"received_data": arbitrary_json}

Examples

1. JSON object

curl -X POST "http://0.0.0.0:6022/" -H  "accept: application/json" -H  "Content-Type: application/json" -d "{\"test_key\":\"test_val\"}" 

Response:

{   "received_data": {     "test_key": "test_val"   } } 

2. JSON array

curl -X POST "http://0.0.0.0:6022/" -H  "accept: application/json" -H  "Content-Type: application/json" -d "[\"foo\",\"bar\"]" 

Response:

{   "received_data": [     "foo",     "bar"   ] } 

If you are not sure about the content type of the incoming data, better to parse the request body.

It can be done as,

from fastapi import FastAPI, Request  app = FastAPI()   @app.post("/") async def root(request: Request):     return {"received_request_body": await request.body()}

The advantage of this method is that the body will contain any kind of data, JSON, form-data, multipart-form-data, etc.

vote vote

64

from fastapi import Request  async def synonyms__select(request: Request):     return await request.json() 

will return a JSON object.

vote vote

60

This is an example to print the content of a Request, it will print the json body (if it is json parsable) otherwise just print the raw bytes of the body.

async def print_request(request):         print(f'request header       : {dict(request.headers.items())}' )         print(f'request query params : {dict(request.query_params.items())}')           try :              print(f'request json         : {await request.json()}')         except Exception as err:             # could not parse json             print(f'request body         : {await request.body()}')               @app.post("/printREQUEST")     async def create_file(request: Request):         try:             await print_request(request)             return {"status": "OK"}         except Exception as err:             logging.error(f'could not print REQUEST: {err}')             return {"status": "ERR"} 

Top 3 video Explaining FastAPI: how to read body as any valid json?

Related QUESTION?