I am currently designing a REST API with FastAPI and using the generated openapi.json specification to generate a client. The client generator I am currently trying to use is limited to OpenAPI 3.0.x.
The generator is complaining about "null" being generated as a possible type for a parameter, which makes sense as that was only introduced in OpenAPI 3.1.0
The offending part of the specification:
"name": "someParameter",
"in": "query",
"required": false,
"schema": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
},
"minItems": 3,
"maxItems": 50
},
{
"type": "null"
}
],
This is being generated from the following endpoint:
@router.get("/{itemId}")
async def readItem(someParameter: Annotated[Optional[list[str]],
Query(title="...",
description="...",
min_length=3, max_length=50)] = None)
I am customizing FastAPI to use the OpenAPI 3.0.1 spec like this:
def customOpenAPI():
openapiSchema = get_openapi(
title = app.title,
openapi_version = "3.0.1",
version = app.version,
summary = app.summary,
description = app.description,
routes = app.routes
)
app.openapi_schema = openapiSchema
return app.openapi_schema
app.openapi = customOpenAPI
A possible solution would be to restructure the endpoint like this:
@router.get("/{itemId}")
async def readItem(someParameter: Annotated(list[str],
Query(title="...",
description="...",
min_length=3, max_length=50,
nullable=True)] = None)
But then I would be losing the Optional typehint which I would like to keep for code readability purposes.
The same problem also applies to Fields in my models:
class SomeModel(BaseModel)
someField: Optional[str] = None
Which I would have to reformat to
class SomeModel(BaseModel)
someField: str = Field(nullable=True, default=None)
Is there any way to get FastAPI to generate the correct OpenAPI 3.0.1 specification while keeping the Optional typehint in my code?
Looks like they don't support it in the code base as described here
The version string of OpenAPI.
FastAPI will generate OpenAPI version 3.1.0, and will output that as the OpenAPI version. But some tools, even though they might be compatible with OpenAPI 3.1.0, might not recognize it as a valid.
So you could override this value to trick those tools into using the generated OpenAPI. Have in mind that this is a hack. But if you avoid using features added in OpenAPI 3.1.0, it might work for your use case.
This is not passed as a parameter to the FastAPI class to avoid giving the false idea that FastAPI would generate a different OpenAPI schema. It is only available as an attribute.
Example from fastapi import FastAPI app = FastAPI() app.openapi_version = "3.0.2"
The only way to configure it for version 3.0.1 is to use the get_openapi(...) function post-process all the fields and then override it in the app. I am suffering from the same problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With