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
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)
^^^
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.