Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@dlax
Copy link
Contributor

@dlax dlax commented Oct 24, 2024

According to the JSON Schema specification, the "type" keyword may be an array of strings (with unique items). Previously, the fastapi.openapi.models.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 tests.

@dlax dlax marked this pull request as draft October 24, 2024 13:26
@dlax dlax force-pushed the allow-list-of-str-in-jsonschema-type branch from 3051b04 to 0587cbb Compare October 24, 2024 13:36
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
@dlax dlax force-pushed the allow-list-of-str-in-jsonschema-type branch from 0587cbb to 53ba155 Compare October 24, 2024 13:54
@dlax dlax marked this pull request as ready for review October 24, 2024 20:51
@svlandeg svlandeg changed the title Accept a list of strings as value for JSON Schema "type" ✨ Accept a list of strings as value for JSON Schema "type" Oct 25, 2024
@svlandeg svlandeg added the feature New feature or request label Oct 25, 2024
@mardiros
Copy link

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

Copy link
Member

@YuriiMotov YuriiMotov left a 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
Copy link
Member

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?

@dlax dlax force-pushed the allow-list-of-str-in-jsonschema-type branch from 6c665d1 to 5190622 Compare July 18, 2025 07:01
@tiangolo
Copy link
Member

Thanks for the work on this! ☕

I'm gonna go with #13639, so I'll close this one now, but thanks for the effort! 🍰

@tiangolo tiangolo closed this Sep 20, 2025
@dlax dlax deleted the allow-list-of-str-in-jsonschema-type branch September 24, 2025 07:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants