跳转至

Pydantic Company

我们根据我认为导致 Pydantic 成功的原则创办了一家公司。

公司公告中了解更多信息.

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 ValidationOpenAPI.

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_ofschema_json_of,可用于以更特殊的方式应用用于 pydantic 模型的模式生成逻辑。 这些函数的行为类似于 BaseModel.schemaBaseModel.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: 当此字段需要默认值时将调用的零参数可调用对象。 除其他用途外,这可用于设置动态默认值。 禁止同时设置 defaultdefault_factory
  • alias: 字段的公开名称
  • title: 如果省略,则使用 field_name.title()
  • description: 如果省略并且注解是子模型,则将使用子模型的文档字符串
  • exclude: 转储(.dict.json)实例时排除此字段。 导出模型部分 中详细描述了确切的语法和配置选项。
  • include: 转储(.dict.json)实例时(仅)包含此字段。 导出模型部分 中详细描述了确切的语法和配置选项。
  • const: 如果存在,此参数必须与字段的默认值相同。
  • gt: 对于数值(intfloatDecimal),向 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)将被逐字添加到字段的模式中

除了使用FieldConfig 类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)按以下优先顺序映射到相应的规范格式(当有等效项可用时):

  1. JSON Schema Core
  2. JSON Schema Validation
  3. OpenAPI Data Types
  4. 标准的 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"
  ]
}