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.
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")
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
Adding elements to a Nested Dictionary Addition of elements to a nested Dictionary can be done in multiple ways. One way to add a dictionary in the Nested dictionary is to add values one be one, Nested_dict[dict][key] = 'value'.
You can access individual items in a nested dictionary by specifying key in multiple square brackets. If you refer to a key that is not in the nested dictionary, an exception is raised.
In Python, a nested dictionary is a dictionary inside a dictionary. It's a collection of dictionaries into one single dictionary.
Items are accessed by their position in a dictionary. All the keys in a dictionary must be of the same type. Dictionaries can be nested to any depth. A dictionary can contain any object type except another dictionary.
Pydantic create_model
function is what you need:
from pydantic import BaseModel, create_model
class Plant(BaseModel):
daytime: Optional[create_model('DayTime', sunrise=(int, ...), sunset=(int, ...))] = None
type: str
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With