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]
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:
BeforeValidator on type annotation cannot access other fields.
field_validator with mode="before" gives access to values, which contains path.
Use np.concatenate to combine input array and path-derived array.
This alone will produce your desired x.info = [1,2,3,4].