对象充当组件的入口和出口点,充当数据流的基本网关。为了创建健壮、可维护的组件,必须在这些对象中定义清晰、结构良好的字段。这确保了不同系统部分之间的数据完整性和可靠交互。就我个人而言,我更喜欢使用 Python 和 FastAPI 框架来开发现代的高性能 API。对于数据验证,Pydantic 是我选择的库,它与 FastAPI 无缝集成,以优雅地强制执行字段约束并保持整个系统的一致性。
from fastapi import FastAPI, HTTPException from pydantic import BaseModel, EmailStr, Field, ValidationError, conint # FastAPI instance app = FastAPI() # Pydantic model for request body validation class User(BaseModel): name: str = Field(..., min_length=3, max_length=50, description="Name must be between 3 and 50 characters") age: conint(gt=0, le=120) = Field(..., description="Age must be between 1 and 120") # Constrained integer type email: EmailStr = Field(..., description="Must be a valid email address") # API route to handle user data submission @app.post("/create-user/") async def create_user(user: User): try: # If validation passes, this will run return {"message": f"User {user.name} created successfully!"} except ValidationError as e: # Catch and return validation errors raise HTTPException(status_code=400, detail=e.errors()) # Sample invalid data invalid_data = {"name": "A", "age": -5, "email": "invalid_email"} # Simulate calling the route with invalid data @app.get("/test-invalid-data/") async def test_invalid_data(): try: user = User(**invalid_data) # Validation will fail here except ValidationError as e: return {"error": e.errors()} # Run the server using: uvicorn <filename>:app --reload
在此示例中,我们演示了 FastAPI 和 Pydantic 如何协同工作以有效处理数据验证。使用 Pydantic 的 BaseModel,我们定义传入请求数据的验证规则。例如,我们利用 EmailStr 自动验证电子邮件格式,从而简化了流程,而无需自定义正则表达式。同样,我们使用 conint(一种受约束的整数类型)来确保年龄落在从 1 到 120 的特定范围内。这种方法增强了可读性和安全性。
在示例代码中,用户模型由姓名、年龄和电子邮件等字段定义,每个字段都有其验证标准。当用户通过 /create-user/ 路由提交数据时,FastAPI 会自动根据这些规则验证输入。如果有效,则用户创建成功;如果没有,FastAPI 会引发 400 Bad Request 并包含详细的错误消息。这显着降低了处理不正确或恶意数据的风险,使 FastAPI 成为安全 API 开发的有力选择。
Pydantic v2 引入了模型级验证,允许您使用 @model_validator 装饰器验证彼此相关的多个字段。此验证在字段验证之后运行,对于确保满足字段之间的某些条件特别有用。例如,您可能想确认事件模型中的 start_date 发生在 end_date 之前:
from pydantic import BaseModel, model_validator from datetime import date class Event(BaseModel): name: str start_date: date end_date: date @model_validator(mode='after') def check_dates(cls, values): start, end = values.get('start_date'), values.get('end_date') if start and end and start >= end: raise ValueError('start_date must be before end_date') return values
在此示例中,@model_validator 检查 start_date 是否早于 end_date。如果不满足此条件,Pydantic 会引发验证错误。这种模型级验证有利于确保准确执行多个字段之间的关系。
Pydantic 允许通过重写 dict() 或 json() 方法来自定义模型字段的序列化。当您想要在序列化期间修改输出格式或排除某些字段时,这非常有用。您还可以使用 @property 装饰器添加包含在序列化中但不属于模型原始数据一部分的计算字段。
下面是自定义序列化的示例,它修改了全名的返回方式,同时从序列化输出中排除密码字段:
from pydantic import BaseModel class User(BaseModel): first_name: str last_name: str password: str # Custom serialization to return the full name @property def full_name(self): return f"{self.first_name} {self.last_name}" # Overriding dict() to exclude the password def dict(self, **kwargs): result = super().dict(**kwargs) result['full_name'] = self.full_name # Add computed field result.pop('password', None) # Remove password from serialization return result # Example usage user = User(first_name="John", last_name="Doe", password="secret123") print(user.dict())
在此示例中,full_name 是一个计算属性,我们重写 dict() 方法以确保从输出中排除密码。像这样的自定义序列化提供了对模型数据如何在 API 或响应中公开的细粒度控制。
Pydantic 与 FastAPI 无缝集成,为请求负载、查询参数和路径参数提供自动数据验证。当您在 FastAPI 端点中定义 Pydantic 模型时,FastAPI 会根据模型的规则自动处理传入数据的解析和验证。如果数据无效,FastAPI 将返回详细的 422 Unprocessable Entity 响应,并包含明确的错误消息。
这是一个简单的例子:
from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class User(BaseModel): username: str age: int @app.post("/users/") async def create_user(user: User): return {"message": f"User {user.username} created successfully!"}
在此示例中,当 POST 请求发送到 /users/ 时,FastAPI 使用 Pydantic 来验证传入的 JSON 数据。如果数据不符合用户模型(例如,缺少用户名或无效年龄),FastAPI 会自动返回错误响应,从而简化输入验证和错误处理。
总之,利用 Pydantic 和 FastAPI 可以通过明确的验证确保数据完整性,从而增强您创建健壮、可维护的应用程序的能力。这种强大的组合简化了开发流程,同时提高了安全性和可靠性,使其成为构建现代 API 的首选。
FastAPI 中的 Pydantic 功能
Pydantic V2 计划
以上是使用 FastAPI 和 Pydantic 构建强大的组件的详细内容。更多信息请关注PHP中文网其他相关文章!