So, I have these enums and models:
class FilterType(str, Enum):
SIMPLE = "simple"
COMPOUND = "compound"
class Operator(str, Enum):
AND = "and"
OR = "or"
class FilterAction(str, Enum):
INCLUDE = "include"
EXCLUDE = "exclude"
class Comparator(str, Enum):
EQUAL = "=="
NOT_EQUAL = "!="
class SimpleFilter(BaseModel):
type = FilterType.SIMPLE
action: FilterAction = FilterAction.EXCLUDE
comparator: Comparator
criterion: Any
class CompoundFilter(BaseModel):
type = FilterType.COMPOUND
operator: Operator = Operator.AND
subfilters: List[Union[SimpleFilter, "CompoundFilter"]] = Field(
default_factory=list
)
CompoundFilter.update_forward_refs()
The most interesting one is of course the CompoundFilter
model. It has the subfilter
field that can contain a list of either the CompountFilter
itself (which has a subfilter
field that can recursively contain ...) or SimpleFilter
.
I want to validate this subfilter
list elements differently depending on the incoming json object. It seems to me that pydantic
is not magical enough (not shaming, it is a great library that I am loving so far) to validate it based on this List[Union[SimpleFilter, "CompoundFilter"]]
. Most probably it is but I am doing something wrong.
Example:
>>> data = {
"type": "compound",
"operator": "and",
"subfilters": [
{
"type": "simple",
"action": "exclude",
"comparator": ">="
}
]
}
>>> CompoundFilter(**sfilters)
CompoundFilter(operator=<Operator.AND: 'and'>, subfilters=[CompoundFilter(operator=<Operator.AND: 'and'>, subfilters=[], type=<FilterType.SIMPLE: 'simple'>)], type=<FilterType.COMPOUND: 'compound'>)
Here, even if I sent a simple filter in the json data, it is being identified as a compound one.
What would be the best way to validate this subfilter
field?