I want to as the title says create a group of attributes a
, b
and c
, such that any combination can be supplied as long as one is given. I have managed to achieve the functionality but it is not reflected in the schema which is what I can't manage to do.
from pydantic import BaseModel, root_validator
class Foo(BaseModel):
a: str | None = None
b: str | None = None
c: str | None = None
@root_validator
def check_at_least_one_given(cls, values):
if not any((values.get('a'), values.get('b'), values.get('c'))):
raise ValueError("At least of a, b, or c must be given")
return values
# Doesn't have required fields
print(Foo.schema_json(indent=2))
{
"title": "Foo",
"type": "object",
"properties": {
"a": {
"title": "A",
"type": "string"
},
"b": {
"title": "B",
"type": "string"
},
"c": {
"title": "C",
"type": "string"
}
}
}
# No error
print(Foo(a="1"))
>>> a='1' b=None c=None
print(Foo(b="2"))
>>> a=None b='2' c=None
print(Foo(c="3"))
>>> a=None b=None c='3'
print(Foo(a="1", b="2"))
>>> a='1' b='2' c=None
print(Foo(a="1", c="3"))
>>> a='1' b=None c='3'
print(Foo(b="2", c="3"))
>>> a=None b='2' c='3'
print(Foo(a="1", b="2", c="3"))
>>> a='1' b='2' c='3'
# Invalid
Foo()
>>> Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "pydantic\main.py", line 342, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for Foo
__root__
At least of a, b, or c must be given (type=value_error)
I want the schema to output something like
{
"title": "Foo",
"type": "object",
"properties": {
"a": {
"title": "A",
"type": "string"
},
"b": {
"title": "B",
"type": "string"
},
"c": {
"title": "C",
"type": "string"
}
},
"required": [
["a", "b", "c"]
]
}
or something else that (probably) more clearly expresses the intent of at least one of these is required.
Is this possible and if so how is it done?