Short way to get all field names of a pydantic class

Question:

Minimal example of the class:

from pydantic import BaseModel

class AdaptedModel(BaseModel):
    def get_all_fields(self, alias=False):
        return list(self.schema(by_alias=alias).get("properties").keys())

class TestClass(AdaptedModel):
    test: str

The way it works:

dm.TestClass.get_all_fields(dm.TestClass)

Is there a way to make it work without giving the class again?

Desired way to get all field names:

dm.TestClass.get_all_fields()

It would also work if the field names are assigned to an attribute. Just any way to make it make it more readable

Asked By: 5th

||

Answers:

Okay the solution is to use a class-method instead of an instance method:

from pydantic import BaseModel, Field

class AdaptedModel(BaseModel):
    @classmethod
    def get_field_names(cls,alias=False):
        return list(cls.schema(alias).get("properties").keys())

class TestClass(AdaptedModel):
    test: str = Field(alias="TEST")

We are using Python 3.6.8 and apparently it was already introduce. For completeness sake can somebody comment since when @classmethod exists? I assume since 3.6.

Answered By: 5th

What about just using __fields__:

from pydantic import BaseModel

class AdaptedModel(BaseModel):
    parent_attr: str

class TestClass(AdaptedModel):
    child_attr: str
        
TestClass.__fields__

Output:

{'parent_attr': ModelField(name='parent_attr', type=str, required=True),
 'child_attr': ModelField(name='child_attr', type=str, required=True)}

This is just a dict and you could get only the field names simply by: TestClass.__fields__.keys()

See model properties: https://pydantic-docs.helpmanual.io/usage/models/#model-properties

Answered By: miksus

If you need also the type of each field you might just use jsonref:

import jsonref
from pprint import pprint
from enum import Enum

class Values(Enum):
    a = 'a'
    b = 'b'


class Mdl(BaseModel):
    par: Values = Field(
        title="par",
        description="description of my parameter"
    )
    par2: str = Field(
        title="par2",
        description="description of my parameter"
    )
    par3: int = Field(
        title="par3",
        description="description of my parameter"
    )

    class Config:
        """ Automatically convert enum to values """
        use_enum_values = True


pprint(jsonref.loads(Mdl.schema_json()))

produces

{'definitions': {'Values': {'description': 'An enumeration.',
                            'enum': ['a', 'b'],
                            'title': 'Values'}},
 'properties': {'par': {'allOf': [{'title': 'Values', 'description': 'An enumeration.', 'enum': ['a', 'b']}],
                        'description': 'description of my parameter',
                        'title': 'MyParameter'},
                'par2': {'description': 'description of my parameter',
                         'title': 'MyParameter',
                         'type': 'string'},
                'par3': {'description': 'description of my parameter',
                         'title': 'MyParameter',
                         'type': 'integer'}},
 'required': ['par', 'par2', 'par3'],
 'title': 'Mdl',
 'type': 'object'}

Latter might further cleaned with

sch = jsonref.loads(Mdl.schema_json())
    for par in sch['properties']:
        if 'allOf' in sch['properties']['par']:
            if 'enum' in sch['properties']['par']['allOf'][0]:
                sch['properties']['par']['title'] = sch['properties']['par']['allOf'][0]['title']
                sch['properties']['par']['allowed_values'] = sch['properties']['par']['allOf'][0]['enum']
                sch['properties']['par'].pop('allOf')

that returns

{'definitions': {'Values': {'description': 'An enumeration.',
                            'enum': ['a', 'b'],
                            'title': 'Values'}},
 'properties': {'par': {'allowed_values': ['a', 'b'],
                        'description': 'description of my parameter',
                        'title': 'Values'},
                'par2': {'description': 'description of my parameter',
                         'title': 'MyParameter',
                         'type': 'string'},
                'par3': {'description': 'description of my parameter',
                         'minimum': 0,
                         'title': 'MyParameter',
                         'type': 'integer'}},
 'required': ['par', 'par2', 'par3'],
 'title': 'Mdl',
 'type': 'object'}
Answered By: Galuoises
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.