How to customize response messages for ReDoc OpenAPI documentation in FastAPI?

1.1k Views Asked by At

I have developed some FastAPI app, and want to customize its redoc documentation. Below is the code for it:

from fastapi import FastAPI
from typing import Optional

import uvicorn

app = FastAPI()

class User(BaseModel):
    username: str

user_list = ["John", "Abrahim", "Kiana"]

#Get method to fetch some value
@app.get('/user/{id}/')
def users(id:int):
    return user_list[id]

#Request Bodies
#Post Method
@app.post('/user')
def add_user(request:User):
    return request.username


if __name__ == "__main__":
    uvicorn.run(app, host="127.0.0.1",port=8000)

As of now I am getting below response in my redoc documentation: enter image description here

I want to add more response codes in redoc like below and also wants to customize the messages against each code. Not sure how to do, so please help in it.

200 - OK    Everything worked as expected.
400 - Bad Request   The request was unacceptable, often due to missing a required parameter.
401 - Unauthorized  No valid API key provided.
402 - Request Failed    The parameters were valid but the request failed.
403 - Forbidden The API key doesn't have permissions to perform the request.
404 - Not Found The requested resource doesn't exist.
409 - Conflict  The request conflicts with another request (perhaps due to using the same idempotent key).
429 - Too Many Requests Too many requests hit the API too quickly. We recommend an exponential backoff of your requests.
500, 502, 503, 504 - Server Errors  Something went wrong on Stripe's end. (These are rare.)
1

There are 1 best solutions below

4
Chris On BEST ANSWER

Straight from the documentation:

You might want to have some predefined responses that apply to many path operations, but you want to combine them with custom responses needed by each path operation.

For those cases, you can use the Python technique of "unpacking" a dict with **dict_to_unpack:

json old_dict = {
    "old key": "old value",
    "second old key": "second old value", 
} 
new_dict = {**old_dict, "new key": "new value"} 

Here, new_dict will contain all the key-value pairs from old_dict plus the new key-value pair:

json {
    "old key": "old value",
    "second old key": "second old value",
    "new key": "new value", 
} 

You can use that technique to re-use some predefined responses in your path operations and combine them with additional custom ones.

Working Example

from typing import Union

from fastapi import FastAPI
from fastapi.responses import FileResponse
from pydantic import BaseModel


class Item(BaseModel):
    id: str
    value: str


responses = {
    404: {"description": "Item not found"},
    302: {"description": "The item was moved"},
    403: {"description": "Not enough privileges"},
}


app = FastAPI()


@app.get(
    "/items/{item_id}",
    response_model=Item,
    responses={**responses, 200: {"content": {"image/png": {}}}},
)
async def read_item(item_id: str, img: Union[bool, None] = None):
    if img:
        return FileResponse("image.png", media_type="image/png")
    else:
        return {"id": "foo", "value": "there goes my hero"}