Skip to content
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

Better support for JSON schema for Callable validators #8208

Open
sydney-runkle opened this issue Nov 22, 2023 · 3 comments
Open

Better support for JSON schema for Callable validators #8208

sydney-runkle opened this issue Nov 22, 2023 · 3 comments
Assignees
Milestone

Comments

@sydney-runkle
Copy link
Member

This isn't a high priority, but I think we could add better default support for Callable type validator JSON schemas, as well as changing the docs to reflect how to change the default schema in these cases.

See more info here: #7957

@Viicos
Copy link
Contributor

Viicos commented Nov 24, 2023

Was hit by this, and here is a use case that could be interesting and would avoid some boilerplate:

from typing import Annotated, Any

from pydantic import BaseModel, BeforeValidator

def _from_string(value: Any):
    if isinstance(value, string):
        return value.split(".")
    return value


class Model(BaseModel):
    screen_position: Annotated[tuple[int, int], BeforeValidator(_from_string)]

Ideally for BeforeValidator, the JSON schema should be updated (in validation mode only) if the callable allow different types (in this case string).

Currently, WithJsonSchema can be used, but really verbose:

class Model(BaseModel):
    screen_position: Annotated[tuple[int, int], BeforeValidator(_from_string), WithJsonSchema({'anyOf': [{'maxItems': 2, 'minItems': 2, 'prefixItems': [{'type': 'integer'}, {'type': 'integer'}], 'type': 'array'}, {'type': 'string'}]})]

Two solutions I've been thinking about:

  • Infer the JSON schema from the type hint of the provided callable to BeforeValidator:
def _from_string(value: tuple[int, int] | str):  # Infer JSON schema from this type
    ...

Could be confusing, because in theory before validator can take any type. Plus, how to handle untyped callables?

  • Add an extra argument to BeforeValidator/field_validator (when mode='before'): BeforeValidator(_from_string, new_type=tuple[int, int] | str)

@sydney-runkle
Copy link
Member Author

Thanks for the example @Viicos! Will keep this in mind when adding this feature 😄!

@sydney-runkle
Copy link
Member Author

Also relevant for PlainSerializer annotations: #8548 (comes as a surprise to some users)

@sydney-runkle sydney-runkle added this to the v2.7.0 milestone Jan 15, 2024
@sydney-runkle sydney-runkle modified the milestones: v2.7.0, v2.8.0 Mar 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants