-
-
Notifications
You must be signed in to change notification settings - Fork 8.6k
✨ Accept a list of strings as value for JSON Schema "type" #12528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
3051b04 to
0587cbb
Compare
According to the JSON Schema specification [1], the "type" keyword may
be an array of strings (with unique items). Previously, the Schema
definition did not allow this and would thus prevent users from using
custom JSON Schema definitions in their field such as `Annotated[...,
WithJsonSchema({"type": ["string", "null"]})` as an alternative to the
`anyOf` which is usually generated (a ValidationError was raised when
generated the OpenAPI definition).
We now accept this "type" variant, as illustrated in modified
test_custom_schema_fields.py.
[1]: https://json-schema.org/draft/2020-12/json-schema-validation#name-type
0587cbb to
53ba155
Compare
|
Note that if you are using rjsf and an optional date, you must do from pydantic import BaseModel, WithJsonSchema
class Foo(BaseModel):
expires_at: Annotated[
date | None, WithJsonSchema({"type": ["string", "null"], "format": "date"})
] = Field(default=None)to get a valid form generated, but the openapi.json is going wrong. Until this fix has been merged and release, I leave with this monkey patch. # type: ignore
from fastapi.openapi import models, utils
class Schema(models.Schema):
type: str | list[str] | None = None
properties: dict[str, "SchemaOrBool"] | None = None
SchemaOrBool = Schema | bool
class Components(models.Components):
schemas: dict[str, Schema | models.Reference] | None = None
class OpenAPI(models.OpenAPI):
components: Components | None = None
Schema.update_forward_refs()
def monkeypatch():
# fix the schema which is not correct
models.Schema = Schema
models.SchemaOrBool = Schema | bool
models.Components = Components
models.OpenAPI = OpenAPI
utils.OpenAPI = OpenAPI |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea in general, but I'm not sure about using set.
I noticed some people don't like that the order of parameters may change.
I've seen a comment that changing the order of elements may lead to Swagger interprets schema differently (can't find that comment now).
There is an alternative PR #13639 that uses list instead of set and also specifies possible values for elements
| # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-structural | ||
| # A Vocabulary for Structural Validation | ||
| type: Optional[str] = None | ||
| type: Optional[Union[str, Set[str]]] = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have to decide here whether we really need to use set or we can use list.
We ensure that all elements are unique, but we lose the order of elements.
I would say it's better to keep the order and leave the responsibility for uniqueness of elements to developer.
Let's think about this.
Maybe we can use list with the validator or constraints?
Co-authored-by: Motov Yurii <[email protected]>
6c665d1 to
5190622
Compare
|
Thanks for the work on this! ☕ I'm gonna go with #13639, so I'll close this one now, but thanks for the effort! 🍰 |
According to the JSON Schema specification, the "type" keyword may be an array of strings (with unique items). Previously, the
fastapi.openapi.models.Schemadefinition did not allow this and would thus prevent users from using custom JSON Schema definitions in their field such asAnnotated[..., WithJsonSchema({"type": ["string", "null"]})as an alternative to theanyOfwhich is usually generated (a ValidationError was raised when generated the OpenAPI definition).We now accept this "type" variant, as illustrated in modified tests.