schema
Note
译者注: JSON Schema 就是一种描述JSON数据长什么样子的规范和格式,详情参考JSON Schema 规范(中文版)
对于将 JSON-schema 转化为 md 文档,参考: jsonschema2md2
对于 在mkdocs 中展示 JSON-schema, 参考: mkdocs-schema-reader
对于 直接根据 JSON-schema 生成 HTML文档, 参考: json-schema-for-humans
Pydantic 允许从模型自动创建 JSON 模式(Schema):
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))
(这个脚本是完整的,它应该“按原样”运行)
输出:
{
"title": "Main",
"description": "This is the description of the main model",
"type": "object",
"properties": {
"foo_bar": {
"$ref": "#/definitions/FooBar"
},
"Gender": {
"$ref": "#/definitions/Gender"
},
"snap": {
"title": "The Snap",
"description": "this is the value of snap",
"default": 42,
"exclusiveMinimum": 30,
"exclusiveMaximum": 50,
"type": "integer"
}
},
"required": [
"foo_bar"
],
"definitions": {
"FooBar": {
"title": "FooBar",
"type": "object",
"properties": {
"count": {
"title": "Count",
"type": "integer"
},
"size": {
"title": "Size",
"type": "number"
}
},
"required": [
"count"
]
},
"Gender": {
"title": "Gender",
"description": "An enumeration.",
"enum": [
"male",
"female",
"other",
"not_given"
],
"type": "string"
}
}
}
生成的模式符合规范: JSON Schema Core, JSON Schema Validation 和 OpenAPI.
BaseModel.schema
将返回模式的字典,而 BaseModel.schema_json
将返回该字典的 JSON 字符串表示。
根据规范,使用的子模型被添加到 definitions
JSON 属性中并被引用。
所有子模型(及其子模型)模式都直接放在顶级“定义”JSON 键中,以便于重用和参考。
带有自定义标题、描述或默认值等修改(通过 Field
类)的“子模型”被递归包含,而不是被引用。
模型的 description
取自类的文档字符串或Field
类的参数 description
。
默认情况下,模式是使用别名作为键生成的,但可以使用模型属性名称通过调用 MainModel.schema/schema_json(by_alias=False)
来生成。
$ref
的格式(上面的"#/definitions/FooBar"
)可以通过使用 ref_template
关键字参数调用 schema()
或 schema_json()
来改变,
例如 ApplePie.schema(ref_template='/schemas/{model}.json#/')
,这里的 {model}
将替换为使用 str.format()
的模型命名。
获取指定类型的schema Getting schema of a specified type¶
Pydantic 包括两个独立的实用程序函数 schema_of
和 schema_json_of
,可用于以更特殊的方式应用用于 pydantic 模型的模式生成逻辑。
这些函数的行为类似于 BaseModel.schema
和 BaseModel.schema_json
,但适用于任意与 pydantic 兼容的类型。
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"
}
},
"oneOf": [
{
"$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"
]
}
}
}
"""
from typing import Literal, Union
from typing 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"
}
},
"oneOf": [
{
"$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"
]
}
}
}
"""
(这个脚本是完整的,它应该“按原样”运行)
Field定制 Field customization¶
可选地,Field
函数可用于提供有关字段和验证的额外信息。
它有以下参数:
default
: (位置参数)字段的默认值。 由于Field
替换了字段的默认值,因此第一个参数可用于设置默认值。 使用省略号 (...
) 表示该字段是必填项。default_factory
: 当此字段需要默认值时将调用的零参数可调用对象。 除其他用途外,这可用于设置动态默认值。 禁止同时设置default
和default_factory
。alias
: 字段的公开名称title
: 如果省略,则使用field_name.title()
description
: 如果省略并且注解是子模型,则将使用子模型的文档字符串exclude
: 转储(.dict
和.json
)实例时排除此字段。 导出模型部分 中详细描述了确切的语法和配置选项。include
: 转储(.dict
和.json
)实例时(仅)包含此字段。 导出模型部分 中详细描述了确切的语法和配置选项。const
: 如果存在,此参数必须与字段的默认值相同。gt
: 对于数值(int
、float
、Decimal
),向 JSON Schema 添加“大于”验证和exclusiveMinimum
注释ge
: 对于数值,这会向 JSON 模式添加“大于或等于”验证和最小值(minimum)
注释lt
: 对于数值,这会向 JSON 模式添加“小于”验证和exclusiveMinimum
注释le
: 对于数值,这会向 JSON 模式添加“小于或等于”验证和最大值(maximum)
注释multiple_of
: 对于数值,这会向 JSON 模式添加“倍数”的验证和multipleOf
的注释max_digits
: 对于Decimal
值,这会添加验证以在小数点内具有最大位数。 它不包括小数点前的零或尾随的小数零。decimal_places
: 对于Decimal
值,这会添加一个验证,以允许最多有多个小数位。 它不包括尾随的小数零。min_items
: 对于列表值,这会向 JSON 模式添加相应的验证和minItems
的注释max_items
: 对于列表值,这会向 JSON 模式添加相应的验证和maxItems
的注释unique_items
: 对于列表值,这会向 JSON 模式添加相应的验证和uniqueItems
的注释min_length
: 对于字符串值,这会向 JSON 模式添加相应的验证和minLength
注释max_length
: 对于字符串值,这会向 JSON 模式添加相应的验证和maxLength
注释allow_mutation
: 一个默认为True
的布尔值。 为 False 时,如果字段是在实例上分配的,则该字段会引发TypeError
。 模型配置必须将validate_assignment
设置为True
才能执行此检查。-
regex
: 对于字符串值,这会向 JSON 模式添加从传递的字符串生成的正则表达式验证和pattern
注释Note
pydantic 使用
re.match
验证字符串,它将正则表达式视为隐式锚定在开头。 相反,JSON Schema 验证器将pattern
关键字视为隐式未锚定的,更像是re.search
所做的。对于互操作性,根据您想要的行为,要么显式地使用
^
锚定您的正则表达式(例如^foo
以匹配任何以foo
开头的字符串),或者显式地允许带有.*?
的任意前缀(例如.*?foo
匹配任何包含子字符串foo
的字符串)。请参阅 #1631,了解 v2 中对 pydantic 行为的可能更改的讨论。
repr
: 一个默认为True
的布尔值。 当为 False 时,该字段应从对象表示中隐藏。**
任何其他关键字参数(例如examples
)将被逐字添加到字段的模式中
除了使用Field
,Config 类 的fields
属性可用于设置除default
之外的所有上述参数。
非强制字段约束 Unenforced Field constraints¶
如果 pydantic 发现未强制执行的约束,则会引发错误。 如果你想强制约束出现在模式中,即使它在解析时没有被检查,你可以使用带有原始模式属性名称的 Field()
的可变参数:
from pydantic import BaseModel, Field, PositiveInt
try:
# this won't work since PositiveInt takes precedence over the
# constraints defined in Field meaning they're ignored
class Model(BaseModel):
foo: PositiveInt = Field(..., lt=10)
except ValueError as e:
print(e)
"""
On field "foo" the following field constraints are set but not enforced:
lt.
For more details see https://docs.pydantic.dev/usage/schema/#unenforced-
field-constraints
"""
# but you can set the schema attribute directly:
# (Note: here exclusiveMaximum will not be enforce)
class Model(BaseModel):
foo: PositiveInt = Field(..., exclusiveMaximum=10)
print(Model.schema())
"""
{
'title': 'Model',
'type': 'object',
'properties': {
'foo': {
'title': 'Foo',
'exclusiveMaximum': 10,
'exclusiveMinimum': 0,
'type': 'integer',
},
},
'required': ['foo'],
}
"""
# if you find yourself needing this, an alternative is to declare
# the constraints in Field (or you could use conint())
# here both constraints will be enforced:
class Model(BaseModel):
# Here both constraints will be applied and the schema
# will be generated correctly
foo: int = Field(..., gt=0, lt=10)
print(Model.schema())
"""
{
'title': 'Model',
'type': 'object',
'properties': {
'foo': {
'title': 'Foo',
'exclusiveMinimum': 0,
'exclusiveMaximum': 10,
'type': 'integer',
},
},
'required': ['foo'],
}
"""
(这个脚本是完整的,它应该“按原样”运行)
typing.Annotated 字段 Fields¶
与其分配Field
值,不如在类型提示中使用typing.Annotated
指定:
from uuid import uuid4
from pydantic import BaseModel, Field
from typing_extensions import Annotated
class Foo(BaseModel):
id: Annotated[str, Field(default_factory=lambda: uuid4().hex)]
name: Annotated[str, Field(max_length=256)] = 'Bar'
from uuid import uuid4
from pydantic import BaseModel, Field
from typing import Annotated
class Foo(BaseModel):
id: Annotated[str, Field(default_factory=lambda: uuid4().hex)]
name: Annotated[str, Field(max_length=256)] = 'Bar'
(这个脚本是完整的,它应该“按原样”运行)
Field
每个字段只能提供一次 - 如果在 Annotated
中使用并作为赋值,将引发错误。
默认值可以在 Annotated
之外设置为指定值,也可以在 Annotated
内使用 Field.default_factory
设置 - Field.default
参数在 Annotated
中不受支持。
对于 3.9 之前的 Python 版本,可以使用 typing_extensions.Annotated
。
修改自定义字段的schema Modifying schema in custom fields¶
自定义字段类型可以使用 __modify_schema__
类方法自定义为它们生成的模式; 有关详细信息,请参阅 自定义数据类型。
__modify_schema__
也可以采用类型为 Optional[ModelField]
的 field
参数。 pydantic 将检查 __modify_schema__
的签名以确定是否应包含 field
参数。
from typing import Any, Callable, Dict, Generator, Optional
from pydantic import BaseModel, Field
from pydantic.fields import ModelField
class RestrictedAlphabetStr(str):
@classmethod
def __get_validators__(cls) -> Generator[Callable, None, None]:
yield cls.validate
@classmethod
def validate(cls, value: str, field: ModelField):
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: Dict[str, Any], 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')
print(MyModel.schema_json(indent=2))
from typing import Any, Callable, Optional
from collections.abc import Generator
from pydantic import BaseModel, Field
from pydantic.fields import ModelField
class RestrictedAlphabetStr(str):
@classmethod
def __get_validators__(cls) -> Generator[Callable, None, None]:
yield cls.validate
@classmethod
def validate(cls, value: str, field: ModelField):
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: dict[str, Any], 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')
print(MyModel.schema_json(indent=2))
from typing import Any
from collections.abc import Callable, Generator
from pydantic import BaseModel, Field
from pydantic.fields import ModelField
class RestrictedAlphabetStr(str):
@classmethod
def __get_validators__(cls) -> Generator[Callable, None, None]:
yield cls.validate
@classmethod
def validate(cls, value: str, field: ModelField):
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: dict[str, Any], field: ModelField | None
):
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')
print(MyModel.schema_json(indent=2))
(这个脚本是完整的,它应该“按原样”运行)
输出:
{
"title": "MyModel",
"type": "object",
"properties": {
"value": {
"title": "Value",
"alphabet": "ABC",
"examples": [
"AAA",
"BBB",
"CCC"
],
"type": "string"
}
},
"required": [
"value"
]
}
JSON Schema 类型(Types)¶
类型、自定义字段类型和约束(如max_length
)按以下优先顺序映射到相应的规范格式(当有等效项可用时):
- JSON Schema Core
- JSON Schema Validation
- OpenAPI Data Types
- 标准的
format
JSON 字段用于为更复杂的string
子类型定义 pydantic 扩展。
从 Python / pydantic 到 JSON Schema 的字段模式映射完成如下:
Python type | JSON Schema Type | Additional JSON Schema | Defined in |
---|---|---|---|
None
|
null
|
JSON Schema Core | |
Same for type(None) or Literal[None]
|
|||
bool
|
boolean
|
JSON Schema Core | |
str
|
string
|
JSON Schema Core | |
float
|
number
|
JSON Schema Core | |
int
|
integer
|
JSON Schema Validation | |
dict
|
object
|
JSON Schema Core | |
list
|
array
|
{"items": {}}
|
JSON Schema Core |
tuple
|
array
|
{"items": {}}
|
JSON Schema Core |
set
|
array
|
{"items": {}, "uniqueItems": true}
|
JSON Schema Validation |
frozenset
|
array
|
{"items": {}, "uniqueItems": true}
|
JSON Schema Validation |
List[str]
|
array
|
{"items": {"type": "string"}}
|
JSON Schema Validation |
And equivalently for any other sub type, e.g. List[int] .
|
|||
Tuple[str, ...]
|
array
|
{"items": {"type": "string"}}
|
JSON Schema Validation |
And equivalently for any other sub type, e.g. Tuple[int, ...] .
|
|||
Tuple[str, int]
|
array
|
{"items": [{"type": "string"}, {"type": "integer"}], "minItems": 2, "maxItems": 2}
|
JSON Schema Validation |
And equivalently for any other set of subtypes. Note: If using schemas for OpenAPI, you shouldn't use this declaration, as it would not be valid in OpenAPI (although it is valid in JSON Schema). | |||
Dict[str, int]
|
object
|
{"additionalProperties": {"type": "integer"}}
|
JSON Schema Validation |
And equivalently for any other subfields for dicts. Have in mind that although you can use other types as keys for dicts with Pydantic, only strings are valid keys for JSON, and so, only str is valid as JSON Schema key types. | |||
Union[str, int]
|
anyOf
|
{"anyOf": [{"type": "string"}, {"type": "integer"}]}
|
JSON Schema Validation |
And equivalently for any other subfields for unions. | |||
Enum
|
enum
|
{"enum": [...]}
|
JSON Schema Validation |
All the literal values in the enum are included in the definition. | |||
SecretStr
|
string
|
{"writeOnly": true}
|
JSON Schema Validation |
SecretBytes
|
string
|
{"writeOnly": true}
|
JSON Schema Validation |
EmailStr
|
string
|
{"format": "email"}
|
JSON Schema Validation |
NameEmail
|
string
|
{"format": "name-email"}
|
Pydantic standard "format" extension |
AnyUrl
|
string
|
{"format": "uri"}
|
JSON Schema Validation |
Pattern
|
string
|
{"format": "regex"}
|
JSON Schema Validation |
bytes
|
string
|
{"format": "binary"}
|
OpenAPI |
Decimal
|
number
|
JSON Schema Core | |
UUID1
|
string
|
{"format": "uuid1"}
|
Pydantic standard "format" extension |
UUID3
|
string
|
{"format": "uuid3"}
|
Pydantic standard "format" extension |
UUID4
|
string
|
{"format": "uuid4"}
|
Pydantic standard "format" extension |
UUID5
|
string
|
{"format": "uuid5"}
|
Pydantic standard "format" extension |
UUID
|
string
|
{"format": "uuid"}
|
Pydantic standard "format" extension |
Suggested in OpenAPI. | |||
FilePath
|
string
|
{"format": "file-path"}
|
Pydantic standard "format" extension |
DirectoryPath
|
string
|
{"format": "directory-path"}
|
Pydantic standard "format" extension |
Path
|
string
|
{"format": "path"}
|
Pydantic standard "format" extension |
datetime
|
string
|
{"format": "date-time"}
|
JSON Schema Validation |
date
|
string
|
{"format": "date"}
|
JSON Schema Validation |
time
|
string
|
{"format": "time"}
|
JSON Schema Validation |
timedelta
|
number
|
{"format": "time-delta"}
|
Difference in seconds (a float ), with Pydantic standard "format" extension
|
Suggested in JSON Schema repository's issues by maintainer. | |||
Json
|
string
|
{"format": "json-string"}
|
Pydantic standard "format" extension |
IPv4Address
|
string
|
{"format": "ipv4"}
|
JSON Schema Validation |
IPv6Address
|
string
|
{"format": "ipv6"}
|
JSON Schema Validation |
IPvAnyAddress
|
string
|
{"format": "ipvanyaddress"}
|
Pydantic standard "format" extension |
IPv4 or IPv6 address as used in ipaddress module
|
|||
IPv4Interface
|
string
|
{"format": "ipv4interface"}
|
Pydantic standard "format" extension |
IPv4 interface as used in ipaddress module
|
|||
IPv6Interface
|
string
|
{"format": "ipv6interface"}
|
Pydantic standard "format" extension |
IPv6 interface as used in ipaddress module
|
|||
IPvAnyInterface
|
string
|
{"format": "ipvanyinterface"}
|
Pydantic standard "format" extension |
IPv4 or IPv6 interface as used in ipaddress module
|
|||
IPv4Network
|
string
|
{"format": "ipv4network"}
|
Pydantic standard "format" extension |
IPv4 network as used in ipaddress module
|
|||
IPv6Network
|
string
|
{"format": "ipv6network"}
|
Pydantic standard "format" extension |
IPv6 network as used in ipaddress module
|
|||
IPvAnyNetwork
|
string
|
{"format": "ipvanynetwork"}
|
Pydantic standard "format" extension |
IPv4 or IPv6 network as used in ipaddress module
|
|||
StrictBool
|
boolean
|
JSON Schema Core | |
StrictStr
|
string
|
JSON Schema Core | |
ConstrainedStr
|
string
|
JSON Schema Core | |
If the type has values declared for the constraints, they are included as validations. See the mapping for constr below.
|
|||
constr(regex='^text$', min_length=2, max_length=10)
|
string
|
{"pattern": "^text$", "minLength": 2, "maxLength": 10}
|
JSON Schema Validation |
Any argument not passed to the function (not defined) will not be included in the schema. | |||
ConstrainedInt
|
integer
|
JSON Schema Core | |
If the type has values declared for the constraints, they are included as validations. See the mapping for conint below.
|
|||
conint(gt=1, ge=2, lt=6, le=5, multiple_of=2)
|
integer
|
{"maximum": 5, "exclusiveMaximum": 6, "minimum": 2, "exclusiveMinimum": 1, "multipleOf": 2}
|
|
Any argument not passed to the function (not defined) will not be included in the schema. | |||
PositiveInt
|
integer
|
{"exclusiveMinimum": 0}
|
JSON Schema Validation |
NegativeInt
|
integer
|
{"exclusiveMaximum": 0}
|
JSON Schema Validation |
NonNegativeInt
|
integer
|
{"minimum": 0}
|
JSON Schema Validation |
NonPositiveInt
|
integer
|
{"maximum": 0}
|
JSON Schema Validation |
ConstrainedFloat
|
number
|
JSON Schema Core | |
If the type has values declared for the constraints, they are included as validations. See the mapping for confloat below.
|
|||
confloat(gt=1, ge=2, lt=6, le=5, multiple_of=2)
|
number
|
{"maximum": 5, "exclusiveMaximum": 6, "minimum": 2, "exclusiveMinimum": 1, "multipleOf": 2}
|
JSON Schema Validation |
Any argument not passed to the function (not defined) will not be included in the schema. | |||
PositiveFloat
|
number
|
{"exclusiveMinimum": 0}
|
JSON Schema Validation |
NegativeFloat
|
number
|
{"exclusiveMaximum": 0}
|
JSON Schema Validation |
NonNegativeFloat
|
number
|
{"minimum": 0}
|
JSON Schema Validation |
NonPositiveFloat
|
number
|
{"maximum": 0}
|
JSON Schema Validation |
ConstrainedDecimal
|
number
|
JSON Schema Core | |
If the type has values declared for the constraints, they are included as validations. See the mapping for condecimal below.
|
|||
condecimal(gt=1, ge=2, lt=6, le=5, multiple_of=2)
|
number
|
{"maximum": 5, "exclusiveMaximum": 6, "minimum": 2, "exclusiveMinimum": 1, "multipleOf": 2}
|
JSON Schema Validation |
Any argument not passed to the function (not defined) will not be included in the schema. | |||
BaseModel
|
object
|
JSON Schema Core | |
All the properties defined will be defined with standard JSON Schema, including submodels. | |||
Color
|
string
|
{"format": "color"}
|
Pydantic standard "format" extension |
顶层Schema生成 Top-level schema generation¶
您还可以生成一个顶级 JSON 架构,该架构仅在其definitions
中包含模型列表和相关子模型:
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))
(这个脚本是完整的,它应该“按原样”运行)
输出:
{
"title": "My Schema",
"definitions": {
"Foo": {
"title": "Foo",
"type": "object",
"properties": {
"a": {
"title": "A",
"type": "string"
}
}
},
"Model": {
"title": "Model",
"type": "object",
"properties": {
"b": {
"$ref": "#/definitions/Foo"
}
},
"required": [
"b"
]
},
"Bar": {
"title": "Bar",
"type": "object",
"properties": {
"c": {
"title": "C",
"type": "integer"
}
},
"required": [
"c"
]
}
}
}
schema定制 Schema customization¶
您可以自定义生成的 $ref
JSON 位置:定义始终存储在键 definitions
下,但可以为引用使用指定的前缀。
如果您需要扩展或修改 JSON Schema 默认定义位置,这将很有用。 例如: 使用 OpenAPI:
import json
from pydantic import BaseModel
from pydantic.schema import schema
class Foo(BaseModel):
a: int
class Model(BaseModel):
a: Foo
# Default location for OpenAPI
top_level_schema = schema([Model], ref_prefix='#/components/schemas/')
print(json.dumps(top_level_schema, indent=2))
(这个脚本是完整的,它应该“按原样”运行)
输出:
{
"definitions": {
"Foo": {
"title": "Foo",
"type": "object",
"properties": {
"a": {
"title": "A",
"type": "integer"
}
},
"required": [
"a"
]
},
"Model": {
"title": "Model",
"type": "object",
"properties": {
"a": {
"$ref": "#/components/schemas/Foo"
}
},
"required": [
"a"
]
}
}
}
也可以扩展/覆盖模型中生成的 JSON 模式。
为此,请使用Config
子类属性schema_extra
。
例如,您可以将 examples
添加到 JSON 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
}
]
}
对于更细粒度的控制,您可以选择将 schema_extra
设置为可调用的,并对生成的模式进行后处理。
可调用对象可以有一个或两个位置参数。
第一个是模式字典。
第二个,如果被接受,将是模型类。
可调用对象预计会就地改变模式字典; 不使用返回值。
例如,可以从模型的“属性”中删除“标题”键:
from typing import Dict, Any, Type
from pydantic import BaseModel
class Person(BaseModel):
name: str
age: int
class Config:
@staticmethod
def schema_extra(schema: Dict[str, Any], model: Type['Person']) -> None:
for prop in schema.get('properties', {}).values():
prop.pop('title', None)
print(Person.schema_json(indent=2))
from typing import Any
from pydantic import BaseModel
class Person(BaseModel):
name: str
age: int
class Config:
@staticmethod
def schema_extra(schema: dict[str, Any], model: type['Person']) -> None:
for prop in schema.get('properties', {}).values():
prop.pop('title', None)
print(Person.schema_json(indent=2))
(这个脚本是完整的,它应该“按原样”运行)
输出:
{
"title": "Person",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "integer"
}
},
"required": [
"name",
"age"
]
}