I want to use the Pydantic to model a "cartesian table" represented as a nested dictionary. Here is an example of what I can expect as input to the NestedCounts
model:
{
"x1": {
"y1": {
"z1": 5,
"z2": 5
},
"y2": {
"z1": 7,
"z2": 3
},
"y3": {
"z1": 8,
"z2": 2
}
},
"x2": {
"y1": {
"z1": 1,
"z2": 9
},
"y2": {
"z1": 2,
"z2": 8
},
"y3": {
"z1": 4,
"z2": 6
}
}
}
The keys at each level will always be strings. The values at the final level will be int, and the values at a non-final level will be a recursive case.
What is the best way to model this using Pydantic? I want to model it in such a way that the native type checking is supported when instantiating a model.
Here is what I am using for now:
from __future__ import annotations
from pydantic import BaseModel
class NestedCounts(BaseModel):
counts: dict[str, int|NestedCounts]
@classmethod
def from_dict(cls, data: dict) -> NestedCounts:
if all(isinstance(v, int) for v in data.values()):
return cls(counts=data)
elif all(isinstance(v, dict) for v in data.values()):
return cls(counts={k: NestedCounts.from_dict(v) for k, v in data.items()})
else:
raise ValueError(f"Invalid dependent variable probabilities. All values must be ints or all values must be dictionaries:\n{data}")
Is there a better way to model such input schema? I want to make sure that whatever I implement allows Pydantic's native type checking.
I want to use the Pydantic to model a "cartesian table" represented as a nested dictionary. Here is an example of what I can expect as input to the NestedCounts
model:
{
"x1": {
"y1": {
"z1": 5,
"z2": 5
},
"y2": {
"z1": 7,
"z2": 3
},
"y3": {
"z1": 8,
"z2": 2
}
},
"x2": {
"y1": {
"z1": 1,
"z2": 9
},
"y2": {
"z1": 2,
"z2": 8
},
"y3": {
"z1": 4,
"z2": 6
}
}
}
The keys at each level will always be strings. The values at the final level will be int, and the values at a non-final level will be a recursive case.
What is the best way to model this using Pydantic? I want to model it in such a way that the native type checking is supported when instantiating a model.
Here is what I am using for now:
from __future__ import annotations
from pydantic import BaseModel
class NestedCounts(BaseModel):
counts: dict[str, int|NestedCounts]
@classmethod
def from_dict(cls, data: dict) -> NestedCounts:
if all(isinstance(v, int) for v in data.values()):
return cls(counts=data)
elif all(isinstance(v, dict) for v in data.values()):
return cls(counts={k: NestedCounts.from_dict(v) for k, v in data.items()})
else:
raise ValueError(f"Invalid dependent variable probabilities. All values must be ints or all values must be dictionaries:\n{data}")
Is there a better way to model such input schema? I want to make sure that whatever I implement allows Pydantic's native type checking.
Share Improve this question edited Mar 14 at 3:51 InSync 11.1k4 gold badges18 silver badges56 bronze badges asked Mar 14 at 2:56 parth.nparth.n 11 Answer
Reset to default 0That's what RootModel
is for:
class NestedCounts(RootModel):
root: dict[str, "NestedCounts | int"]
input_dict = {
"x1": {"y1": {"z1": 5, "z2": 5}, "y2": {"z1": 7, "z2": 3}, "y3": {"z1": 8, "z2": 2}},
"x2": {"y1": {"z1": 1, "z2": 9}, "y2": {"z1": 2, "z2": 8}, "y3": {"z1": 4, "z2": 6}},
}
nested_counts = NestedCounts.model_validate(input_dict)