List all properties defined on a Pydantic BaseModel

97 views Asked by At

Is there an elegant way to list all properties defined on a Pydantic BaseModel?

It's possible to extract the list of fields via BaseModel.model_fields and the list of computed fields via BaseModel.model_computed_fields, but there does not appear to be a method for listing all the properties.

from pydantic import BaseModel

class Test(BaseModel):

    field: str

    @property
    def len_field(self) -> int:
        return len(self.field)
    
    @property
    def first_char(self) -> str:
        return self.field[0]

    
t = Test(field="abc")
print(t.model_fields, dir(t))
# how do I list "len_field", "first_char"?
2

There are 2 answers

0
SultanOrazbayev On

One approach, based on this answer, is to use inspect.getmembers:

from inspect import getmembers

print(getmembers(Test, lambda v: isinstance(v, property)))

# [('__fields_set__', <property at 0x114b98130>),
#  ('first_char', <property at 0x15627d4e0>),
#  ('len_field', <property at 0x15627eb60>),
#  ('model_computed_fields', <property at 0x114b6bfb0>),
#  ('model_extra', <property at 0x114b98180>),
#  ('model_fields_set', <property at 0x114b980e0>)]

From here, it should be possible to filter out the standard pydantic properties.

1
Zachary Duvall On

There's nothing built into pydantic for this that I'm aware of, but you can use dir combined with isinstance to filter them:

from pydantic import BaseModel

class Test(BaseModel):

    field: str

    @property
    def len_field(self) -> int:
        return len(self.field)
    
    @property
    def first_char(self) -> str:
        return self.field[0]
    
    @classmethod
    def get_properties(cls):
        return [name for name in dir(cls) if isinstance(getattr(cls, name), property)]
    
Test.get_properties() # >>> ['first_char', 'len_field']