0

I am creating a API to return pydantic backed object, with optional / "fetchable" fields that might not be fetched based on the API parameter passed in.

when accessing these optional data fields in the object, i want to add an assertion that the field is actually fetched.

A "ok" way is adding getter and setter for each field, but i think it is very ugly, hard to add additional support like serialization etc, and there are lots of such fields in the object:

 _field_a: int | NotFetched = NOT_FETCHED
 @property
 def field_a(self) -> int: 
   return assert_fetched(self._field_a)

 @field_a.setter
 def field_a(self, value):
   self._field_a = value

A "better" way is using descriptor class:

class FetchableField(Generic[T]):
    def __set_name__(self, owner: type, name: str) -> None:
        self.public_name = name
        self.private_name = f"_{name}"

    def __get__(self, instance: Any, owner: type | None = None) -> T:
        if instance is None:
            return self  # pyright: ignore[reportReturnType]
        return assert_fetched(
            getattr(instance, self.private_name, NOT_FETCHED),
            self.public_name,
        )

    def __set__(self, instance: Any, value: T) -> None:
        setattr(instance, self.private_name, value)

...
_field_a: int | NotFetched = NOT_FETCHED # optional, 
field_a: int = FetchableField()
...

However, it seems like Pydantic is not working with descriptor, and then:

 obj = Object()
 obj.a # will equal to a <FetchableField object> without calling the getter function in FetchableField
1
  • I think what you're describing is similar to what SQLModel recommends (sqlmodel.tiangolo.com/tutorial/fastapi/multiple-models/…), which is to create a base Pydantic class which contains only the required fields. You can then subclass this class with the additional fetchable fields depending on the args passed in and return those instead? Commented Oct 29 at 10:24

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.