Search code examples
pythonswaggerfastapiswagger-uiopenapi

TypeError: Object of type 'type' is not JSON serializable


The code works fine in Postman and provides a valid response but fails to generate the OpenAPI/Swagger UI automatic docs.

class Role(str, Enum):
     Internal = "internal"
     External = "external"


class Info(BaseModel):
    id: int
    role: Role

class AppInfo(Info):
    info: str


@app.post("/api/v1/create", status_code=status.HTTP_200_OK)
async def create(info: Info, apikey: Union[str, None] = Header(str)):
    if info:
        alias1 = AppInfo(info="Portal Gun", id=123, role=info.role)
        alias2 = AppInfo(info="Plumbus", id=123, , role=info.role)
        info_dict.append(alias1.dict())
        info_dict.append(alias2.dict())

        
        return {"data": info_dict}
    else:
        
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Please provide the input"
        )

Error received:

TypeError: Object of type 'type' is not JSON serializable

Solution

  • Issue

    The reason you get the following error in the console (Note that this error could also be raised by other causes—see here):

    TypeError: Object of type 'type' is not JSON serializable
    

    as well as the error below in the browser, when trying to load the OpenAPI/Swagger UI autodocs at /docs:

    Fetch error
    Internal Server Error /openapi.json
    

    is due to the following line in your code:

    apikey: Union[str, None] = Header(str)
                                      ^^^
    

    Solution

    When declaring a Header parameter (or any other type of parameter, i.e., Path, Query, Cookie, etc), the first value that is passed to the Header class constructor (i.e., __init__ method) is the default value, which can either be None or some default value based on the type you specified for the parameter—in your case that could be some string value, e.g., 'some-api-key', not the type str). Since you defined the parameter as Optional, you could simply pass None as the default value:

    apikey: Union[str, None] = Header(None)
    

    Please have a look at this answer and this answer for more details on Optional parameters in FastAPI.