跳到内容

网络类型

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,
)

Url 约束。

属性

名称 类型 描述
max_length int | None

url 的最大长度。默认为 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

defined_constraints 属性

defined_constraints: dict[str, Any]

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

AnyUrl

AnyUrl(url: str | Url | _BaseUrl)

基类: _BaseUrl

所有 URL 的基本类型。

  • 允许任何方案
  • 顶级域名 (TLD) 不是必需的
  • 主机不是必需的

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

  • scheme: URL 方案 (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
127
128
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
127
128
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
127
128
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
127
128
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
127
128
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

一种将接受任何文件 URL 的类型。

  • 主机不是必需的
源代码位于 pydantic/networks.py
127
128
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
127
128
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
347
348
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
127
128
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
127
128
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
127
128
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
347
348
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
127
128
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
347
348
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
127
128
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
127
128
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
127
128
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
127
128
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
1040
1041
1042
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
1264
1265
1266
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
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