GZZ
GZZ

Reputation: 708

Pydantic models good practice in FastAPI

I am building a REST API with FastAPI and I really like the tool, especially the integration with Pydantic and OpenAPI.

For instance I can write the model taken by an endpoint as

class Model(BaseModel):
    field1: str = Field(default=...)
    field2: int = Field(default=...)
    field3: List[int] = Field(default=...)
    field4: float = Field(default=...)
    class Config:
        schema_extra = {
            "example": {
                'field1': 'example 1',
                'field2': 1,
                'field3': [1, 2],
                'field4': 1.3,
            }
        }

I find however that I have quite some repetitions in my code as for example if I want to create another class inheriting from Model that adds another field field5, I would need to re-write the Config class in order to define the new example.

Is there a good way of doing this? For example, is there any tool that allows you to define the fields with all the properties and example and then creating the class Model from a definition of what it requires to include?

Or any other pattern that is better suited for this is also welcome.

Upvotes: 4

Views: 2646

Answers (2)

Yaakov Bressler
Yaakov Bressler

Reputation: 12018

You could create a base schema extra and modify within each instantiation:

base_schema_extra = {
    "example": {
        'field1': 'example 1',
        'field2': 1,
        'field3': [1, 2],
        'field4': 1.3,
    }
}

class Model(BaseModel):
    field1: str = Field(default=...)
    field2: int = Field(default=...)
    field3: List[int] = Field(default=...)
    field4: float = Field(default=...)

    class Config:
        schema_extra = base_schema_extra


class Model2(BaseModel):
    field1: str = Field(default=...)
    field2: int = Field(default=...)
    field3: List[int] = Field(default=...)
    field4: float = Field(default=...)
    field5: bool = Field(default=...)

    class Config:
        schema_extra = dict(**base_schema_extra, **{'field5': True})

You can also inherit classes using the following:

class Model3(Model2):
    field6: bool = Field(default=...)

    class Config(Model.Config):
        schema_extra = dict(**Model.Config.schema_extra, **{'field6': False})

Upvotes: 6

Rishad
Rishad

Reputation: 191

Declare another class that inherits from Base Model class. Add another field. The Config will remain the same but an extra example field.

class ChildModel(Model):
    field5: str = Field(default=...)
    class Config:
        schema_extra = {
            "example": {
                'field1': 'example 1',
                'field2': 1,
                'field3': [1, 2],
                'field4': 1.3,
                'field5': 'foo'
            }
        }

It will work, no issue

Upvotes: 0

Related Questions