Generated schemas do not follow the OpenAPI specification (FastAPI v0.66+)
See original GitHub issueFirst Check
- I added a very descriptive title to this issue.
- I used the GitHub search to find a similar issue and didn’t find it.
- I searched the FastAPI documentation, with the integrated search.
- I already searched in Google “How to X in FastAPI” and didn’t find any information.
- I already read and followed all the tutorial in the docs and didn’t find an answer.
- I already checked if it is not related to FastAPI but to Pydantic.
- I already checked if it is not related to FastAPI but to Swagger UI.
- I already checked if it is not related to FastAPI but to ReDoc.
Commit to Help
- I commit to help with one of those options 👆
Example Code
import json
from pydantic import BaseModel, Field
from fastapi import FastAPI
from fastapi import __version__ as fastapi_version
class Model(BaseModel):
field: str = Field("foo", const=True)
app = FastAPI(title=f"Created with FastAPI v{fastapi_version}")
@app.get("/", response_model=Model)
def root():
return Model(field="foo")
print(json.dumps(Model.schema(), indent=2))
print(json.dumps(app.openapi(), indent=2))
Description
With fastapi==0.68.0
and pydantic==1.8.2
, the above MWE produces an invalid OpenAPI schema due to the handling of extra keys introduced in the last release. The inclusion of the const
key is not supported in OpenAPI 3 (see Supported Keywords).
Here is a diff between the schema created for v0.65.2 vs v0.68 (also tested with 0.66, 0.67 with the same results).
// ...
},
"components": {
"schemas": {
"Model": {
"title": "Model",
"type": "object",
"properties": {
"field": {
"title": "Field",
"type": "string",
+ "const": "foo"
}
// ...
This regression is caused by the addition of extra = "allow"
to fastapi.openapi.models.Schema
in (#1429) (see also the comment https://github.com/tiangolo/fastapi/pull/1429#issuecomment-889256569). This is something we ran into when updating FastAPI at https://github.com/Materials-Consortia/optimade-python-tools/pull/887.
While I would also like to be able to use extension keys (with the appropriate x-
prefix) too, this change now makes it hard to use some standard pydantic features. My suggestion would be to enumerate the keys from JSON schema that OpenAPI does not support (linked above) and handle those separately in the Config
for Schema
. Perhaps any “extra” key that is not in this list could be prepended with a x-my-app
prefix defined on the init of the FastAPI
instance. I’m happy to have a go at implementing this, if desired.
Operating System
Linux
Operating System Details
No response
FastAPI Version
0.68.0
Python Version
3.8.5
Additional Context
I’ve made two gists for the OpenAPI schemas from v0.68.0 and v0.65.2:
- 0.65.2: https://gist.github.com/ml-evs/99b33f68b74a0c197e970f9222faa2bc
- 0.68.0: https://gist.github.com/ml-evs/824f9ac510f92d4e180a4e984d1da38d
You can pass the raw json through the online swagger validator to verify:
-
$ curl -s https://validator.swagger.io/validator/debug\?url\=https://gist.githubusercontent.com/ml-evs/99b33f68b74a0c197e970f9222faa2bc/raw/71d056de37a942bb9bc26943151c477a97aa18f4/fastapi_v0.65.2_openapi.json | jq {}
-
$ curl -s https://validator.swagger.io/validator/debug\?url\=https://gist.githubusercontent.com/ml-evs/824f9ac510f92d4e180a4e984d1da38d/raw/d25b9c3a7802702ced6e3f7a1aa60e017ac9b339/fastapi_v0.68.0_openapi.json | jq { "messages": [ "attribute components.schemas.Model.const is unexpected" ], "schemaValidationMessages": [ { "level": "error", "domain": "validation", "keyword": "oneOf", "message": "instance failed to match exactly one schema (matched 0 out of 2)", "schema": { "loadingURI": "#", "pointer": "/definitions/Components/properties/schemas/patternProperties/^[a-zA-Z0-9\\.\\-_]+$" }, "instance": { "pointer": "/components/schemas/Model" } } ] }
Issue Analytics
- State:
- Created 2 years ago
- Reactions:3
- Comments:19 (10 by maintainers)
Top GitHub Comments
Hey all! Some additional info: Pydantic generates JSON Schema, and that is re-used by OpenAPI.
But OpenAPI 3.0.x is based on an old version of JSON Schema that didn’t have
const
and also had some additional incompatibilities. OpenAPI 3.1.x is based on JSON Schema v7, which hasconst
.So, about
const
, the ideal would be to be able to upgrade OpenAPI to 3.1.x. In fact, the currently generated OpenAPI schema is a bit more compatible with 3.1.x than 3.0.x. But I haven’t been able to update the generated version by FastAPI because Swagger UI is not compatible with 3.1.x, it doesn’t even try to render, it just explodes. So I can’t upgrade that resulting version yet. The best way to move forward for that would be to improve/add support in Swagger UI to OpenAPI 3.1.x.Now, about extra fields included by default in the output JSON Schema, I hope a future version of Pydantic will have something like
Field(schema_extra={})
instead of just including any extra args there. That would allow explicitly adding custom stuff that should be included in the output JSON Schema and avoid side effects for other use cases.Just a quick note that Pydantic v2 will have its own independent field
json_schema_extra
instead of taking everything else and putting it in the JSON Schema output. 🎉That will at least help understand and debug these use cases better. 🤓