Context
I'm trying to validate/parse some data with pydantic
.
I want to specify that the dict can have a key daytime
, or not.
If it does, I want the value of daytime
to include both sunrise
and sunset
.
e.g. These should be allowed:
{
'type': 'solar',
'daytime': {
'sunrise': 4, # 4am
'sunset': 18 # 6pm
}
}
And
{
'type': 'wind'
# daytime key is omitted
}
And
{
'type': 'wind',
'daytime': None
}
But I want to fail validation for
{
'type': 'solar',
'daytime': {
'sunrise': 4
}
}
Because this has a daytime
value, but no sunset value.
MWE
I've got some code that does this. If I run this script, it executes successfully.
from pydantic import BaseModel, ValidationError
from typing import List, Optional, Dict
class DayTime(BaseModel):
sunrise: int
sunset: int
class Plant(BaseModel):
daytime: Optional[DayTime] = None
type: str
p = Plant.parse_obj({'type': 'wind'})
p = Plant.parse_obj({'type': 'wind', 'daytime': None})
p = Plant.parse_obj({
'type': 'solar',
'daytime': {
'sunrise': 5,
'sunset': 18
}})
try:
p = Plant.parse_obj({
'type': 'solar',
'daytime': {
'sunrise': 5
}})
except ValidationError:
pass
else:
raise AssertionError("Should have failed")
Question
What I'm wondering is, is this how you're supposed to use pydantic for nested data?
I have lots of layers of nesting, and this seems a bit verbose.
Is there any way to do something more concise, like:
class Plant(BaseModel):
daytime: Optional[Dict[('sunrise', 'sunset'), int]] = None
type: str