はじめに
前回の記事では、Pydanticの基本的なモデル定義やバリデーションの仕組みを紹介しました。
今回はもう少し応用的な機能として、以下のトピックを取り上げます。
-
1. 型制約付きフィールド:
constr
,conint
などを活用した厳格なバリデーション - 2. カスタム型とユニオン型: より複雑なデータを扱うためのヒント
- 3. field_validatorの使いどころ: フィールド間の相関チェック
- 4. BaseSettingsで環境変数管理: 便利な設定管理機能
- 5. FastAPIとの簡単な連携例: API開発との相性抜群のPydanticを体験
それぞれ実装例を交えながら、Google Colabやローカル環境などで試しやすい形で紹介します。
!pip install pydantic pydantic[email]
1. 型制約付きフィールド (constr, conintなど)
Pydanticでは標準の型ヒントに加えて、特別な制約を追加できる機能が用意されています。たとえば、文字列の長さや正規表現チェック、数値の最大値・最小値などが簡単に設定可能です。
from pydantic import BaseModel, constr, conint
class Product(BaseModel):
name: constr(min_length=3, max_length=20) # 文字列の長さを3〜20文字に制約
price: conint(ge=0, le=9999) # 整数に範囲を設定
# 正しいデータ
item = Product(name="Apple", price=120)
print(item)
# 間違ったデータ(価格が範囲外)
try:
item_ng = Product(name="AB", price=50000)
except ValueError as e:
print("Validation Error:", e)
- constr などを使うと、1行で高度な文字列バリデーションが設定できる
- 価格など数値チェックは conint や confloat を使うと便利
2. カスタム型とユニオン型
2-1. カスタム型 (例: URLやEmailStr など)
Pydanticは標準ライブラリを拡張したカスタム型が用意されています。例えばEmailStr
やHttpUrl
などをフィールド型として指定するだけで、形式チェックが自動で行われます。
from pydantic import BaseModel
from pydantic import BaseModel, EmailStr, HttpUrl
class ContactInfo(BaseModel):
email: EmailStr
website: HttpUrl
valid_contact = ContactInfo(email="test@example.com", website="https://example.com")
print(valid_contact)
try:
invalid_contact = ContactInfo(email="invalid-email", website="invalid_url")
except ValueError as e:
print("Validation Error:", e)
2-2. ユニオン型 (Union)
複数の型を許容するフィールドにはUnion
を使用します。
from typing import Union
from pydantic import BaseModel
class Payment(BaseModel):
amount: Union[int, str] # 数値または文字列を許可
pay_data1 = Payment(amount=1000)
pay_data2 = Payment(amount="FREE")
print(pay_data1, pay_data2)
try:
pay_data3 = Payment(amount=["NG"])
except ValueError as e:
print("Validation Error:", e)
3. field_validatorの使いどころ
単一のフィールドごとの検証: @field_validator
モデル全体(複数フィールドの相関チェックなど): @model_validator
from pydantic import BaseModel, model_validator
class Order(BaseModel):
product_name: str
quantity: int
price_per_item: float
@model_validator(mode="after")
def total_price_must_not_exceed_limit(cls, model):
total_price = model.quantity * model.price_per_item
if total_price > 100000:
raise ValueError(f"Total price ({total_price}) exceeds the allowed limit.")
return model
# 正しいデータ
order_ok = Order(product_name="Computer", quantity=5, price_per_item=10000)
print(order_ok)
# エラーとなるデータ
try:
order_ng = Order(product_name="Computer", quantity=50, price_per_item=3000)
except ValueError as e:
print("Validation Error:", e)
4. BaseSettingsで環境変数管理
Pydanticには、設定ファイルや環境変数から値を読み込むためのBaseSettings
クラスがあります。
!pip install pydantic-settings
import os
from pydantic_settings import BaseSettings, SettingsConfigDict
# 環境変数の例
os.environ["API_KEY"] = "your_secret_key_123"
class AppConfig(BaseSettings):
api_key: str
debug_mode: bool = False
model_config = SettingsConfigDict(env_file=".env")
# 設定の取得と表示
config = AppConfig()
print("API Key:", config.api_key)
print("Debug Mode:", config.debug_mode)
5. FastAPIとの簡単な連携例
!pip install fastapi uvicorn
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
name: str
age: int
@app.post("/users/")
def create_user(user: User):
return {"message": f"User {user.name} with age {user.age} created!"}
-
uvicorn main:app --reload
でサーバーを起動し、APIを確認できます。
まとめ
- Pydantic v2では、
@field_validator
を活用して柔軟なバリデーションが可能 - 型制約付きフィールドやカスタム型を使用することで、データ整合性を強化
-
BaseSettings
を使用して環境変数や設定ファイルを管理 - FastAPIとの連携でバリデーションをAPIに統合