JSON#
JSON format is a widely used method for data exchange over the internet. This page explores various approaches to crafting JSON responses within the FastAPI framework.
import requests
!docker run --rm -itd\
--name fastapi_json_responses\
-v ./json_files/app.py:/app.py\
-p 8000:8000 \
fastapi_experiment \
uvicorn --host 0.0.0.0 --reload app:app
64f8096c46f92f2392710e94830f4e5a57b708d0b7d7b85a7b77a6c8d5d1d274
Note: Remember to stop the container after you’re finished.
!docker stop fastapi_json_responses
fastapi_json_responses
String as json#
When building an API that primarily returns JSON data, it’s common to encounter scenarios where you need to provide pre-serialized JSON responses. In such cases, you can simply return a string containing the serialized JSON, which the browser will interpret as JSON.
Let’s consider an example where our API simply returns the string “hello”.
%%writefile json_files/app.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def get() -> str:
return 'hello'
Overwriting json_files/app.py
Now let’s response of the endpoint and check it’s headers.
for key, item in requests.get("http://localhost:8000").headers.items():
print(key, item)
date Fri, 16 Aug 2024 08:35:28 GMT
server uvicorn
content-length 7
content-type application/json
The header Content-Type: application/json
indicates that the API has returned JSON data.
JSONResponse object#
FastAPI provides a special class, fastapi.responses.JSONResponse
, which allows for more fine-grained control over JSON responses. The following cell shows the docstring for this object.
from fastapi.responses import JSONResponse
JSONResponse?
Init signature:
JSONResponse(
content: 'typing.Any',
status_code: 'int' = 200,
headers: 'typing.Mapping[str, str] | None' = None,
media_type: 'str | None' = None,
background: 'BackgroundTask | None' = None,
) -> 'None'
Docstring: <no docstring>
File: ~/.local/lib/python3.10/site-packages/starlette/responses.py
Type: type
Subclasses: UJSONResponse, ORJSONResponse
The following cell defines a FastAPI application that utilizes JSONResponse
as the object to be returned. It defines content
, status_code
, and headers
, which we will explore to see how they influence the response.
%%writefile json_files/app.py
from fastapi import FastAPI
from fastapi.responses import JSONResponse
app = FastAPI()
@app.get("/")
def get() -> JSONResponse:
return JSONResponse(
content={"key": "value"},
status_code=255,
headers={"name": "Fedor", "surname": "Kobak"}
)
Overwriting json_files/app.py
The following cell sends a request to the newly created API and prints the content
, status_code
, and headers
of the response.
response = requests.get("http://localhost:8000/")
print("content", response.content)
print("status code", response.status_code)
print("headers", response.headers)
content b'{"key":"value"}'
status code 255
headers {'date': 'Tue, 20 Aug 2024 12:04:25 GMT', 'server': 'uvicorn', 'name': 'Fedor', 'surname': 'Kobak', 'content-length': '15', 'content-type': 'application/json'}
So, the content
and status code
are exactly as we specified. The headers
also include the specified key/value pairs, along with the necessary ones.