0

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?

Jahongir Rahmonov
  • 13,083
  • 10
  • 47
  • 91

0 Answers0