pydantic Schema
作者:互联网
1.根据模型自动创建JSON结构
from enum import Enum
from pydantic import BaseModel, Field
class FooBar(BaseModel):
count: int
size: float = None
class Gender(str, Enum):
male = 'male'
female = 'female'
other = 'other'
not_given = 'not_given'
class MainModel(BaseModel):
"""
This is the description of the main model
"""
foo_bar: FooBar = Field(...)
gender: Gender = Field(None, alias='Gender')
snap: int = Field(
42,
title='The Snap',
description='this is the value of snap',
gt=30,
lt=50,
)
class Config:
title = 'Main'
# this is equivalent to json.dumps(MainModel.schema(), indent=2):
print(MainModel.schema_json(indent=2)) # indent=2 表示缩进空格数
2.获取指定类型的JSON架构
schema_of
schema_json_of
from typing import Literal, Union
from typing_extensions import Annotated
from pydantic import BaseModel, Field, schema_json_of
class Cat(BaseModel):
pet_type: Literal['cat']
cat_name: str
class Dog(BaseModel):
pet_type: Literal['dog']
dog_name: str
Pet = Annotated[Union[Cat, Dog], Field(discriminator='pet_type')]
print(schema_json_of(Pet, title='The Pet Schema', indent=2))
"""
{
"title": "The Pet Schema",
"discriminator": {
"propertyName": "pet_type",
"mapping": {
"cat": "#/definitions/Cat",
"dog": "#/definitions/Dog"
}
},
"anyOf": [
{
"$ref": "#/definitions/Cat"
},
{
"$ref": "#/definitions/Dog"
}
],
"definitions": {
"Cat": {
"title": "Cat",
"type": "object",
"properties": {
"pet_type": {
"title": "Pet Type",
"enum": [
"cat"
],
"type": "string"
},
"cat_name": {
"title": "Cat Name",
"type": "string"
}
},
"required": [
"pet_type",
"cat_name"
]
},
"Dog": {
"title": "Dog",
"type": "object",
"properties": {
"pet_type": {
"title": "Pet Type",
"enum": [
"dog"
],
"type": "string"
},
"dog_name": {
"title": "Dog Name",
"type": "string"
}
},
"required": [
"pet_type",
"dog_name"
]
}
}
}
"""
BaseModel.schema
import json
from pydantic import BaseModel
from pydantic.schema import schema
class Foo(BaseModel):
a: str = None
class Model(BaseModel):
b: Foo
class Bar(BaseModel):
c: int
top_level_schema = schema([Model, Bar], title='My Schema')
print(json.dumps(top_level_schema, indent=2))
BaseModel.schema_json
3.修改字段中的Schema展示
from typing import Optional
from pydantic import BaseModel, Field
from pydantic.fields import ModelField
class RestrictedAlphabetStr(str):
@classmethod
def __get_validators__(cls):
yield cls.validate
@classmethod
def validate(cls, value, field: ModelField):
"""
增加校验,严格限制value值必须是ABC
如果不对字段进行限制,可以不用实现该方法和__get_validators__方法
"""
alphabet = field.field_info.extra['alphabet']
if any(c not in alphabet for c in value):
raise ValueError(f'{value!r} is not restricted to {alphabet!r}')
return cls(value)
@classmethod
def __modify_schema__(cls, field_schema, field: Optional[ModelField]):
if field:
alphabet = field.field_info.extra['alphabet']
field_schema['examples'] = [c * 3 for c in alphabet]
class MyModel(BaseModel):
value: RestrictedAlphabetStr = Field(alphabet='ABC')
# Schema结构中增加examples示例:__modify_schema__
print(MyModel.schema_json(indent=2))
print(MyModel(value="ABC"))
4.通过配置扩展Schema
from pydantic import BaseModel
class Person(BaseModel):
name: str
age: int
class Config:
schema_extra = {
'examples': [
{
'name': 'John Doe',
'age': 25,
}
]
}
print(Person.schema_json(indent=2))
"""
{
"title": "Person",
"type": "object",
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"age": {
"title": "Age",
"type": "integer"
}
},
"required": [
"name",
"age"
],
"examples": [
{
"name": "John Doe",
"age": 25
}
]
}
"""
5.自定义schema
- 使用model层字段中的描述信息来填充schema中的描述
from typing import Dict, Any, Type
from sqlalchemy import Column, String, Integer
from sqlalchemy.ext.declarative import declarative_base
from pydantic import BaseModel, Field
Base = declarative_base()
class PersonOrm(Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True, nullable=False, comment="primary_key")
name = Column(String(63))
class Person(BaseModel):
id: int = Field(...)
name: str = Field(..., title='The Snap', description='this is the value of snap')
class Config:
orm_mode = True
orm_model = PersonOrm
@staticmethod
def schema_extra(schema: Dict[str, Any], model: Type['Person']) -> None:
model_obj = model.Config().orm_model()
for key, value in schema.get('properties', {}).items():
if value.get("description"):
continue
if hasattr(model_obj, key):
description = model_obj.metadata.sorted_tables[0].columns._index[key].comment
value["description"] = description
person_orm = PersonOrm(id=123, name='Testing')
person_model = Person.from_orm(person_orm)
print(person_model.schema_json(indent=2))
"""
C:\Users\fatpuffer\AppData\Local\pypoetry\Cache\virtualenvs\baseapi-FOv_RZhh-py3.7\Scripts\python.exe F:/projects/BaseApi/__init__.py
{
"title": "Person",
"type": "object",
"properties": {
"id": {
"title": "Id",
"type": "integer",
"description": "primary_key"
},
"name": {
"title": "The Snap",
"description": "this is the value of snap",
"type": "string"
}
},
"required": [
"id",
"name"
]
}
"""
标签:name,title,BaseModel,import,Schema,type,pydantic,schema 来源: https://www.cnblogs.com/puffer/p/16382411.html