PHP前端开发

Pydantic:手动验证的终结! ✨

百变鹏仔 3天前 #Python
文章标签 Pydantic

pydantic 是一个 python 数据验证和设置管理库。它使用 python 类型提示来验证和解析数据,确保您的代码能够处理正确结构化和类型化的数据。通过利用 python 的类似数据类的模型结构,pydantic 可以轻松定义复杂数据的模式,并以干净的 python 方式自动验证和序列化/反序列化数据。让我们来探讨一下主要功能:

数据验证

使用 python 的类型提示根据模式自动验证输入数据。

from pydantic import basemodel, validationerrorclass user(basemodel):    id: int    name: str    email: str# valid inputuser = user(id=1, name="john doe", email="john@example.com")print(user)# invalid inputtry:    user = user(id="not-an-integer", name="jane", email="jane@example.com")except validationerror as err:    print(err)

每当你想定义数据模型时,请使用 pydantic.basemodel!

功能验证

pydantic 提供了强大的工具,不仅可以验证数据模型,还可以验证函数的输入和输出。这是使用 @validate_call 装饰器实现的,允许您对函数参数和返回值强制执行严格的数据验证。如果提供的参数或返回类型与预期类型不匹配,则会引发 validationerror。

from pydantic import validate_call@validate_calldef greet(name: str, age: int) -> str:    return f"hello {name}, you are {age} years old."# valid inputprint(greet("alice", 30))  # output: hello alice, you are 30 years old.# invalid inputtry:    greet("bob", "not-a-number")except exception as e:    print(e)

通过在 @validate_call 中启用 validate_return 标志,pydantic 还将根据其带注释的返回类型验证函数的返回值。这可确保函数遵循预期的输出模式。

from pydantic import validate_call@validate_call(validate_return=true)def calculate_square(number: int) -> int:    return number ** 2  # correct return type# valid input and returnprint(calculate_square(4))  # output: 16# invalid return value@validate_call(validate_return=true)def broken_square(number: int) -> int:    return str(number ** 2)  # incorrect return typetry:    broken_square(4)except exception as e:    print(e)

解析

pydantic 可以将复杂的嵌套结构(包括 json 数据)解析为模型对象。

from pydantic import basemodelfrom typing import listclass item(basemodel):    name: str    price: floatclass order(basemodel):    items: list[item]    total: float# json-like datadata = {    "items": [        {"name": "apple", "price": 1.2},        {"name": "banana", "price": 0.8}    ],    "total": 2.0}order = order(**data) print(order) # items=[item(name='apple', price=1.2), item(name='banana', price=0.8)] total=2.0

序列化和反序列化

pydantic 模型可以序列化为 json 或字典并重构回来。

from pydantic import basemodelclass user(basemodel):    id: int    name: str    email: str# create a model instanceuser = user(id=1, name="alice", email="alice@example.com")# serialize to dictionary and jsonuser_dict = user.model_dump()user_json = user.model_dump(mode='json')print("dictionary:", user_dict)print("json:", user_json)# deserialize back to the modelnew_user = user.model_validate(user_json)print("parsed user:", new_user)

灵活的验证

数据验证不是强制类型验证。例如,如果您定义一个模型,其中 id、due_date 和优先级字段分别为 int、bool 和 datetime 类型,则可以传递:

from sensei import apimodelfrom datetime import datetimeclass task(apimodel):    id: int    due_date: datetime    priority: booltask = task(due_date='2024-10-15t15:30:00', id="1", priority="yes")print(task)

结果将是

task(id=1, due_date=datetime.datetime(2024, 10, 15, 15, 30), priority=true)

自定义验证

您还可以使用验证器在模型中定义自定义验证逻辑。它们允许您应用更复杂的验证规则,这些规则无法使用内置类型或字段约束轻松表达。验证器是通过 field_validator 装饰器或 field 对象定义的。您可以将一个或多个字段名称传递给 field_validator,以确定哪些字段将使用此验证器,或者通过“*”为每个字段应用验证器。

from typing import Anyfrom pydantic import Field, field_validator, EmailStr, BaseModelclass User(BaseModel):    id: int    username: str = Field(pattern=r'^w+$')    email: EmailStr    age: int = Field(18, ge=14)    is_active: bool = True    roles: list[str]    # Define validator executed 'before' internal parsing    @field_validator('roles', mode='before')    def _validate_roles(cls, value: Any):        return value.split(',') if isinstance(value, str) else valueuser = User(id=1, username='john', email='john@example.com', roles='student,singer')print(user) # id=1 username='john' email='john@example.com' age=18 is_active=True roles=['student', 'singer']

开源项目

有很多由 pydantic 支持的开源项目。让我们探索其中最好的:

快速api

pydantic 最突出的用例之一是 fastapi,这是一个使用 python 构建 api 的现代 web 框架。 fastapi 广泛使用 pydantic 模型进行请求正文验证、查询参数和响应模式。

老师

fastapi 是为构建 api 而设计的,而 sensei 则是为快速、轻松地包装这些 api 而设计的。由 sensei 提供支持的 api 客户端可确保用户获得相关的数据模型,并且不会出现令人困惑的错误。

sqlmodel 和 typer

sqlmodeltyper 是 fastapi 的创建者 sebastián ramírez 开发的两个出色的项目。

sqlmodel 是一个旨在简化 python 应用程序中的数据库交互的库。 sqlmodel 构建于 sqlalchemypydantic 之上,将 orm 的强大功能与数据验证和序列化的便利性结合在一起。

typer 是一个使用 python 创建命令行界面 (cli) 应用程序的框架。它通过使用 python 的类型提示自动生成用户友好的 cli 命令和帮助文本来简化流程。