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架构
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"
]
}
}
}
"""
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))
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"
]
}
"""
5.Field字段属性
default
:字段默认值,...
或空,代表必填;None
代表可选
default_factory
:可以设置动态默认值,不能和default同时设置
alias
:字段设置别名,在dict获取时,可通过设置by_alias=True
参数得到别名对象
title
:生成的schema文档title字段值
description
:schema中对字段的描述
exclude
:表示字段是否被排除在外,不进行展示
include
:表示是否仅展示该字段
const
:布尔值,必须和default保持一致,schema中可以看到该字段的值就是default默认值
gt
:对于数值,大于
该参数设置的值
ge
:对于数值,大于或等于
该参数设置的值
lt
:对于数值,小于
该参数设置的值
le
:对于数值,小于或等于
该参数设置的值
multiple_of
:对于整数,校验倍数,比如multiple_of=2
,则该参数接收的值只能是2的倍数
max_digits
:对于Decimal
类型,校验位数,不包括小数点,仅计算整数位+小数位的最大长度
(小数位末尾的0不算在内,整数部分开头的0不算在内),不超过该参数设置
decimal_places
:对于Decimal
类型,校验小位数(小数位末尾的0不算在内),不超过该参数设置
min_items
:对于列表(typing下的List)值,长度不能小于该参数设置的值
max_items
:对于列表值,长度不能大于该参数设置的值
unique_items
:对于列表值,不能有重复的元素
min_length
:对于字符串值,最小长度不能小于该参数设置的值
max_length
:对于字符串值,最大长度不能大于该参数设置的值
allow_mutation
:布尔值,该字段参数是否可以被修改
regex
:对于字符串值,可以直接传递正则进行校验