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

Question:

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
Asked By: Tanu

||

Answers:

I think the problem might be at:

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

in the async function create()

Maybe the function or class Header() doesn’t accept str as an input?

Although I don’t really know what that function does tho//what library it is from.

Answered By: kaliiiiiiiii

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.

Answered By: Chris