pythonserializationpydantic

How to use Pydantic field in another field for serialization/deserialization purposes


I would like to solve the following problem with Pydantic (latest version), with Python 3.x.

While deserializing, I want to use the field "path", path contains another array that I want to combine with my input array so I can get a bigger array at the end.

Here is the code that I simplified to explain my problem. I don't understand how I can use my field path in the deserializing function, I want to pass it as an argument.

import pydantic
import numpy as np
from pydantic import BeforeValidator, PlainSerializer
from typing_extensions import Annotated

def my_serializer(data:np.ndarray):
    return str(data)

def my_deserializer(data) -> np.ndarray:
    " operations using path"
    # x= combinate arrays
    return x

NDArraySpecial = Annotated[
    np.ndarray,
    PlainSerializer(my_serializer, return_type=np.ndarray),
    BeforeValidator(my_deserializer),
]

class MyArray(pydantic.BaseModel):
    path: str = Field(frozen=True, exclude=True)
    info: NDArraySpecial | None = Field(default=None)

x = MyArray(path="mypath", info= np.array([[1,2]]))

# input array  [1,2]
# path contains array [3,4]
# desired output x.info = [1,2,3,4]

Solution

  • Change the BeforeValidator to a field_validator and access values so you can use path during deserialization. Minimal lines to change:

    from pydantic import field_validator
    
    class MyArray(pydantic.BaseModel):
        path: str = Field(frozen=True, exclude=True)
        info: NDArraySpecial | None = Field(default=None)
    
        @field_validator("info", mode="before")
        @classmethod
        def combine_with_path(cls, v, values):
            if v is None:
                return v
            path_array = np.array([3, 4])  # example: get array from values['path'] if needed
            return np.concatenate([v, path_array])
    

    Why:

    This alone will produce your desired x.info = [1,2,3,4].