When you create a FastAPIpath operation you can normally return any data from it: a dict, a list, a Pydantic model, a database model, etc.
By default, FastAPI would automatically convert that return value to JSON using the jsonable_encoder explained in JSON Compatible Encoder.
Then, behind the scenes, it would put that JSON-compatible data (e.g. a dict) inside of a JSONResponse that would be used to send the response to the client.
But you can return a JSONResponse directly from your path operations.
It might be useful, for example, to return custom headers or cookies.
Because FastAPI doesn't do any change to a Response you return, you have to make sure it's contents are ready for it.
For example, you cannot put a Pydantic model in a JSONResponse without first converting it to a dict with all the data types (like datetime, UUID, etc) converted to JSON-compatible types.
For those cases, you can use the jsonable_encoder to convert your data before passing it to a response:
You could also use from starlette.responses import JSONResponse.
FastAPI provides the same starlette.responses as fastapi.responses just as a convenience for you, the developer. But most of the available responses come directly from Starlette.
The example above shows all the parts you need, but it's not very useful yet, as you could have just returned the item directly, and FastAPI would put it in a JSONResponse for you, converting it to a dict, etc. All that by default.
Now, let's see how you could use that to return a custom response.
Let's say that you want to return an XML response.
You could put your XML content in a string, put it in a Response, and return it:
fromfastapiimportFastAPI,Responseapp=FastAPI()@app.get("/legacy/")defget_legacy_data():data="""<?xml version="1.0"?> <shampoo> <Header> Apply shampoo here. </Header> <Body> You'll have to use soap here. </Body> </shampoo> """returnResponse(content=data,media_type="application/xml")