跳转到内容

网络类型

networks 模块包含常见网络相关字段的类型。

MAX_EMAIL_LENGTH 模块属性

MAX_EMAIL_LENGTH = 2048

电子邮件的最大长度。这是一个有些随意但与大多数实现所允许的相比非常宽松的数字。

UrlConstraints 数据类

UrlConstraints(
    max_length: int | None = None,
    allowed_schemes: list[str] | None = None,
    host_required: bool | None = None,
    default_host: str | None = None,
    default_port: int | None = None,
    default_path: str | None = None,
    preserve_empty_path: bool | None = None,
)

Url 约束。

属性

名称 类型 描述
max_length int | None

url 的最大长度。默认为 None

allowed_schemes list[str] | None

允许的 scheme。默认为 None

host_required bool | None

主机是否为必需项。默认为 None

default_host str | None

默认主机。默认为 None

default_port int | None

默认端口。默认为 None

default_path str | None

默认路径。默认为 None

preserve_empty_path bool | None

是否保留空的 URL 路径。默认为 None

defined_constraints 属性

defined_constraints: dict[str, Any]

获取约束与非 None 值的键/值映射。用于核心模式更新。

AnyUrl

AnyUrl(url: str | Url | _BaseUrl)

基类:_BaseUrl

所有 URL 的基本类型。

  • 允许任何 scheme
  • 不要求顶级域名 (TLD)
  • 不要求主机

假设输入 URL 为 http://samuel:[email protected]:8000/the/path/?query=here#fragment=is;this=bit,这些类型会导出以下属性

  • scheme:URL scheme (http),总是被设置。
  • host:URL 主机 (example.com)。
  • username:可选的用户名,如果包含的话 (samuel)。
  • password:可选的密码,如果包含的话 (pass)。
  • port:可选的端口 (8000)。
  • path:可选的路径 (/the/path/)。
  • query:可选的 URL 查询(例如,GET 参数或“搜索字符串”,如 query=here)。
  • fragment:可选的片段 (fragment=is;this=bit)。
源代码位于 pydantic/networks.py
130
131
def __init__(self, url: str | _CoreUrl | _BaseUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

AnyHttpUrl

AnyHttpUrl(url: str | Url | _BaseUrl)

基类:AnyUrl

一个接受任何 http 或 https URL 的类型。

  • 不要求 TLD
  • 不要求主机
源代码位于 pydantic/networks.py
130
131
def __init__(self, url: str | _CoreUrl | _BaseUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

HttpUrl

HttpUrl(url: str | Url | _BaseUrl)

基类:AnyUrl

一个接受任何 http 或 https URL 的类型。

  • 不要求 TLD
  • 不要求主机
  • 最大长度 2083
from pydantic import BaseModel, HttpUrl, ValidationError

class MyModel(BaseModel):
    url: HttpUrl

m = MyModel(url='http://www.example.com')  # (1)!
print(m.url)
#> http://www.example.com/

try:
    MyModel(url='ftp://invalid.url')
except ValidationError as e:
    print(e)
    '''
    1 validation error for MyModel
    url
      URL scheme should be 'http' or 'https' [type=url_scheme, input_value='ftp://invalid.url', input_type=str]
    '''

try:
    MyModel(url='not a url')
except ValidationError as e:
    print(e)
    '''
    1 validation error for MyModel
    url
      Input should be a valid URL, relative URL without a base [type=url_parsing, input_value='not a url', input_type=str]
    '''
  1. 注意:mypy 更倾向于 m = MyModel(url=HttpUrl('http://www.example.com')),但 Pydantic 无论如何都会将字符串转换为 HttpUrl 实例。

“国际化域名”(例如,主机或 TLD 中包含非 ASCII 字符的 URL)将通过 punycode 进行编码(参见这篇文章,很好地解释了为什么这很重要)。

from pydantic import BaseModel, HttpUrl

class MyModel(BaseModel):
    url: HttpUrl

m1 = MyModel(url='http://puny£code.com')
print(m1.url)
#> http://xn--punycode-eja.com/
m2 = MyModel(url='https://www.аррӏе.com/')
print(m2.url)
#> https://www.xn--80ak6aa92e.com/
m3 = MyModel(url='https://www.example.珠宝/')
print(m3.url)
#> https://www.example.xn--pbt977c/

主机名中的下划线

在 Pydantic 中,除了 TLD 外,域名的所有部分都允许使用下划线。从技术上讲,这可能是错误的——理论上主机名不能包含下划线,但子域名可以。

解释如下;考虑以下两种情况

  • exam_ple.co.uk:主机名是 exam_ple,它包含下划线,因此不应该被允许。
  • foo_bar.example.com:主机名是 example,它应该被允许,因为下划线在子域名中。

如果没有详尽的 TLD 列表,就不可能区分这两种情况。因此,允许使用下划线,但如果需要,你随时可以在验证器中进行进一步的验证。

此外,Chrome、Firefox 和 Safari 目前都接受 http://exam_ple.com 作为 URL,所以我们与大公司(至少是知名公司)的做法一致。

源代码位于 pydantic/networks.py
130
131
def __init__(self, url: str | _CoreUrl | _BaseUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

AnyWebsocketUrl

AnyWebsocketUrl(url: str | Url | _BaseUrl)

基类:AnyUrl

一个接受任何 ws 或 wss URL 的类型。

  • 不要求 TLD
  • 不要求主机
源代码位于 pydantic/networks.py
130
131
def __init__(self, url: str | _CoreUrl | _BaseUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

WebsocketUrl

WebsocketUrl(url: str | Url | _BaseUrl)

基类:AnyUrl

一个接受任何 ws 或 wss URL 的类型。

  • 不要求 TLD
  • 不要求主机
  • 最大长度 2083
源代码位于 pydantic/networks.py
130
131
def __init__(self, url: str | _CoreUrl | _BaseUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

FileUrl

FileUrl(url: str | Url | _BaseUrl)

基类:AnyUrl

一个接受任何 file URL 的类型。

  • 不要求主机
源代码位于 pydantic/networks.py
130
131
def __init__(self, url: str | _CoreUrl | _BaseUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

FtpUrl

FtpUrl(url: str | Url | _BaseUrl)

基类:AnyUrl

一个接受 ftp URL 的类型。

  • 不要求 TLD
  • 不要求主机
源代码位于 pydantic/networks.py
130
131
def __init__(self, url: str | _CoreUrl | _BaseUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

PostgresDsn

PostgresDsn(url: str | MultiHostUrl | _BaseMultiHostUrl)

基类:_BaseMultiHostUrl

一个接受任何 Postgres DSN 的类型。

  • 要求用户信息
  • 不要求 TLD
  • 要求主机
  • 支持多个主机

如果需要进一步的验证,验证器可以使用这些属性来强制执行特定的行为

from pydantic import (
    BaseModel,
    HttpUrl,
    PostgresDsn,
    ValidationError,
    field_validator,
)

class MyModel(BaseModel):
    url: HttpUrl

m = MyModel(url='http://www.example.com')

# the repr() method for a url will display all properties of the url
print(repr(m.url))
#> HttpUrl('http://www.example.com/')
print(m.url.scheme)
#> http
print(m.url.host)
#> www.example.com
print(m.url.port)
#> 80

class MyDatabaseModel(BaseModel):
    db: PostgresDsn

    @field_validator('db')
    def check_db_name(cls, v):
        assert v.path and len(v.path) > 1, 'database must be provided'
        return v

m = MyDatabaseModel(db='postgres://user:pass@localhost:5432/foobar')
print(m.db)
#> postgres://user:pass@localhost:5432/foobar

try:
    MyDatabaseModel(db='postgres://user:pass@localhost:5432')
except ValidationError as e:
    print(e)
    '''
    1 validation error for MyDatabaseModel
    db
      Assertion failed, database must be provided
    assert (None)
     +  where None = PostgresDsn('postgres://user:pass@localhost:5432').path [type=assertion_error, input_value='postgres://user:pass@localhost:5432', input_type=str]
    '''
源代码位于 pydantic/networks.py
350
351
def __init__(self, url: str | _CoreMultiHostUrl | _BaseMultiHostUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

host 属性

host: str

必需的 URL 主机。

CockroachDsn

CockroachDsn(url: str | Url | _BaseUrl)

基类:AnyUrl

一个接受任何 Cockroach DSN 的类型。

  • 要求用户信息
  • 不要求 TLD
  • 要求主机
源代码位于 pydantic/networks.py
130
131
def __init__(self, url: str | _CoreUrl | _BaseUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

host 属性

host: str

必需的 URL 主机。

AmqpDsn

AmqpDsn(url: str | Url | _BaseUrl)

基类:AnyUrl

一个接受任何 AMQP DSN 的类型。

  • 要求用户信息
  • 不要求 TLD
  • 不要求主机
源代码位于 pydantic/networks.py
130
131
def __init__(self, url: str | _CoreUrl | _BaseUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

RedisDsn

RedisDsn(url: str | Url | _BaseUrl)

基类:AnyUrl

一个接受任何 Redis DSN 的类型。

  • 要求用户信息
  • 不要求 TLD
  • 要求主机(例如,rediss://:pass@localhost
源代码位于 pydantic/networks.py
130
131
def __init__(self, url: str | _CoreUrl | _BaseUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

host 属性

host: str

必需的 URL 主机。

MongoDsn

MongoDsn(url: str | MultiHostUrl | _BaseMultiHostUrl)

基类:_BaseMultiHostUrl

一个接受任何 MongoDB DSN 的类型。

  • 不要求用户信息
  • 不要求数据库名称
  • 不要求端口
  • 用户信息可以在没有用户部分的情况下传递(例如,mongodb://mongodb0.example.com:27017)。
源代码位于 pydantic/networks.py
350
351
def __init__(self, url: str | _CoreMultiHostUrl | _BaseMultiHostUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

KafkaDsn

KafkaDsn(url: str | Url | _BaseUrl)

基类:AnyUrl

一个接受任何 Kafka DSN 的类型。

  • 要求用户信息
  • 不要求 TLD
  • 不要求主机
源代码位于 pydantic/networks.py
130
131
def __init__(self, url: str | _CoreUrl | _BaseUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

NatsDsn

NatsDsn(url: str | MultiHostUrl | _BaseMultiHostUrl)

基类:_BaseMultiHostUrl

一个接受任何 NATS DSN 的类型。

NATS 是一种为日益超连接的世界而构建的连接技术。它是一种单一技术,使应用程序能够跨越任何云供应商、本地、边缘、Web 和移动设备以及设备的组合进行安全通信。更多信息:https://nats.io

源代码位于 pydantic/networks.py
350
351
def __init__(self, url: str | _CoreMultiHostUrl | _BaseMultiHostUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

MySQLDsn

MySQLDsn(url: str | Url | _BaseUrl)

基类:AnyUrl

一个接受任何 MySQL DSN 的类型。

  • 要求用户信息
  • 不要求 TLD
  • 不要求主机
源代码位于 pydantic/networks.py
130
131
def __init__(self, url: str | _CoreUrl | _BaseUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

MariaDBDsn

MariaDBDsn(url: str | Url | _BaseUrl)

基类:AnyUrl

一个接受任何 MariaDB DSN 的类型。

  • 要求用户信息
  • 不要求 TLD
  • 不要求主机
源代码位于 pydantic/networks.py
130
131
def __init__(self, url: str | _CoreUrl | _BaseUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

ClickHouseDsn

ClickHouseDsn(url: str | Url | _BaseUrl)

基类:AnyUrl

一个接受任何 ClickHouse DSN 的类型。

  • 要求用户信息
  • 不要求 TLD
  • 不要求主机
源代码位于 pydantic/networks.py
130
131
def __init__(self, url: str | _CoreUrl | _BaseUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

SnowflakeDsn

SnowflakeDsn(url: str | Url | _BaseUrl)

基类:AnyUrl

一个接受任何 Snowflake DSN 的类型。

  • 要求用户信息
  • 不要求 TLD
  • 要求主机
源代码位于 pydantic/networks.py
130
131
def __init__(self, url: str | _CoreUrl | _BaseUrl) -> None:
    self._url = _build_type_adapter(self.__class__).validate_python(url)._url

host 属性

host: str

必需的 URL 主机。

EmailStr

信息

要使用此类型,你需要安装可选的 email-validator

pip install email-validator

验证电子邮件地址。

from pydantic import BaseModel, EmailStr

class Model(BaseModel):
    email: EmailStr

print(Model(email='[email protected]'))
#> email='[email protected]'

NameEmail

NameEmail(name: str, email: str)

基类:Representation

信息

要使用此类型,你需要安装可选的 email-validator

pip install email-validator

验证一个名称和电子邮件地址的组合,如 RFC 5322 所规定。

NameEmail 有两个属性:nameemail。如果未提供 name,则会从电子邮件地址中推断出来。

from pydantic import BaseModel, NameEmail

class User(BaseModel):
    email: NameEmail

user = User(email='Fred Bloggs <[email protected]>')
print(user.email)
#> Fred Bloggs <[email protected]>
print(user.email.name)
#> Fred Bloggs

user = User(email='[email protected]')
print(user.email)
#> fred.bloggs <[email protected]>
print(user.email.name)
#> fred.bloggs
源代码位于 pydantic/networks.py
1043
1044
1045
def __init__(self, name: str, email: str):
    self.name = name
    self.email = email

IPvAnyAddress

验证一个 IPv4 或 IPv6 地址。

from pydantic import BaseModel
from pydantic.networks import IPvAnyAddress

class IpModel(BaseModel):
    ip: IPvAnyAddress

print(IpModel(ip='127.0.0.1'))
#> ip=IPv4Address('127.0.0.1')

try:
    IpModel(ip='http://www.example.com')
except ValueError as e:
    print(e.errors())
    '''
    [
        {
            'type': 'ip_any_address',
            'loc': ('ip',),
            'msg': 'value is not a valid IPv4 or IPv6 address',
            'input': 'http://www.example.com',
        }
    ]
    '''

IPvAnyInterface

验证一个 IPv4 或 IPv6 接口。

IPvAnyNetwork

验证一个 IPv4 或 IPv6 网络。

validate_email

validate_email(value: str) -> tuple[str, str]

使用 email-validator 进行电子邮件地址验证。

返回

类型 描述
tuple[str, str]

一个包含电子邮件本地部分(或“美化”电子邮件地址的名称)和规范化电子邮件的元组。

抛出

类型 描述
PydanticCustomError

如果电子邮件无效。

注意

请注意

  • 不允许使用原始 IP 地址(字面量)的域名部分。
  • 会处理 "John Doe <[email protected]>" 风格的“美化”电子邮件地址。
  • 会从地址的开头和结尾去除空格,但不会引发错误。
源代码位于 pydantic/networks.py
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
def validate_email(value: str) -> tuple[str, str]:
    """Email address validation using [email-validator](https://pypi.ac.cn/project/email-validator/).

    Returns:
        A tuple containing the local part of the email (or the name for "pretty" email addresses)
            and the normalized email.

    Raises:
        PydanticCustomError: If the email is invalid.

    Note:
        Note that:

        * Raw IP address (literal) domain parts are not allowed.
        * `"John Doe <[email protected]>"` style "pretty" email addresses are processed.
        * Spaces are striped from the beginning and end of addresses, but no error is raised.
    """
    if email_validator is None:
        import_email_validator()

    if len(value) > MAX_EMAIL_LENGTH:
        raise PydanticCustomError(
            'value_error',
            'value is not a valid email address: {reason}',
            {'reason': f'Length must not exceed {MAX_EMAIL_LENGTH} characters'},
        )

    m = pretty_email_regex.fullmatch(value)
    name: str | None = None
    if m:
        unquoted_name, quoted_name, value = m.groups()
        name = unquoted_name or quoted_name

    email = value.strip()

    try:
        parts = email_validator.validate_email(email, check_deliverability=False)
    except email_validator.EmailNotValidError as e:
        raise PydanticCustomError(
            'value_error', 'value is not a valid email address: {reason}', {'reason': str(e.args[0])}
        ) from e

    email = parts.normalized
    assert email is not None
    name = name or parts.local_part
    return name, email