ホームページ >バックエンド開発 >Python チュートリアル >FastAPI と Pydantic を使用した堅牢なコンポーネントの構築

FastAPI と Pydantic を使用した堅牢なコンポーネントの構築

DDD
DDDオリジナル
2024-10-07 16:12:29920ブラウズ

Building Robust Components with FastAPI and Pydantic

明確に定義されたオブジェクトを活用して効率的なデータ検証を行う

オブジェクトはコンポーネントの入口点と出口点として機能し、データ フローの基本的なゲートウェイとして機能します。堅牢で保守しやすいコンポーネントを作成するには、これらのオブジェクト内に明確で適切に構造化されたフィールドを定義することが不可欠です。これにより、データの整合性と、さまざまなシステム部分間の信頼性の高い相互作用が保証されます。個人的には、最新の高パフォーマンス API を開発するには、Python と FastAPI フレームワークを併用することを好みます。データ検証に関しては、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 を使用したカスタム フィールド/モデルの検証

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 でのカスタム シリアル化

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 または応答でモデル データを公開する方法をきめ細かく制御できます。

FastAPI と Pydantic の統合

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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。