How to use a single validator on multiple fields of the same type in Pydantic?

2.5k views Asked by At

I'm parsing the output of ffprobe that looks like this:

{
        "filename": "G:\\ffmpeg testing\\input_file\\test_file.wmv",
        "nb_streams": 2,
        "nb_programs": 0,
        "format_name": "asf",
        "format_long_name": "ASF (Advanced / Active Streaming Format)",
        "start_time": "0.000000",
        "duration": "2155.050000",
        "size": "567194391",
        "bit_rate": "2105545",
        "probe_score": 100,
        "tags": {
            "WMFSDKNeeded": "0.0.0.0000",
            "DeviceConformanceTemplate": "MP@HL",
            "WMFSDKVersion": "11.0.5721.5265",
            "IsVBR": "0"
        }
    }

With the following Pydantic schema:

class ProbeFormatModel(BaseModel):
    """Represents the format package in ffprobe output"""

    filename: Path
    nb_streams: int
    nb_programs: int
    format_name: str
    format_long_name: str
    start_time: float
    duration: float
    size: int
    bit_rate: int
    probe_score: int
    tags: dict

As you can see in the JSON, there are multiple float and int fields that appear as strings in the JSON. Currently, I'm using a validator to evaluate those fields and poulate them as floats as ints instead of strings... Likes so:

    @validator('start_time','duration','size','bit_rate', pre=True)
    def validate_str_to_float_evaluation(cls, input_value):
        """Tries to evaluate float/int value denoted by division between two integers like so '0/0'or '100/75' or just plain ints like '7' """
    try:
        evaluated_result = eval(input_string)
    except ZeroDivisionError as e:
        # "0/0" is an acceptable value
        evaluated_result = 0.0
    return evaluated_result

I wonder if there is a way to tell Pydantic to use the same validator for all fields of the same type (As in, int and float) instead of explicitly writing down each field in the decorator.

The documentation shows there is a star (*) operator that will use the validator for all fields. But I only want to use it on a subset of fields.

0

There are 0 answers