简体   繁体   中英

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.

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})

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM