Upgrade to Pro — share decks privately, control downloads, hide ads and more …

モデルの定義に基づくバリデーションを実現するためのpydantic入門

 モデルの定義に基づくバリデーションを実現するためのpydantic入門

Daiki Katsuragawa

July 12, 2022
Tweet

More Decks by Daiki Katsuragawa

Other Decks in Programming

Transcript

  1. 課題を解決する“pydantic” • “pydantic”とは ◦ モデルを定義することでデータのバリデーションを実現するライブラリ ◦ 辞書型・JSONとの変換も可能であり部品の入出力に有用 • 課題①:入出力で扱うデータの定義がわからない(可読性の課題) ◦

    モデルの定義により把握が可能に(規約化) • 課題②:入出力で扱うデータが正しくない(堅牢性の課題) ◦ 定義に基づくバリデーションにより正しいデータのみが存在する状態に 5 !pip install pydantic
  2. pydanticの利用例〜Userクラスの定義①〜 6 from pydantic import BaseModel, Field class User(BaseModel): id:

    int name: str age: int = Field(ge=20) external_data = { 'id': 1, 'name': 'パイソン 太郎', 'age': 20 } user = User.parse_obj(external_data) 型、有効範囲の定義 定義を満たす インスタンスの生成 Userクラスの定義の 読み取りが可能 (例:ageは20以上)
  3. pydanticの利用例〜Userクラスの定義②〜 7 from pydantic import BaseModel, Field class User(BaseModel): id:

    int name: str age: int = Field(ge=20) external_data = { 'id': 1, 'name': 'パイソン 太郎', 'age': 19 } user = User.parse_obj(external_data) 有効範囲外の値 ValidationError
  4. pydanticの利用例〜ValidationErrorの中身〜 8 (省略) ValidationError: 1 validation error for User age

    ensure this value is greater than or equal to 20 (type=value_error.number.not_ge; limit_value=20) エラーの詳細を確認可能 (例:ageの20以上という定義を満たしていない)
  5. pydanticの利用例〜Userクラスを引数とする関数①〜 9 from pydantic import validate_arguments @validate_arguments def input_user(user :

    User) -> None: pass external_data = { 'id': 1, 'name': 'パイソン 太郎', 'age': 20 } input_user(external_data) 引数のバリデーションを 実行するデコレーター pydanticで定義した クラスも引数として指定
  6. pydanticの利用例〜Userクラスを引数とする関数②〜 10 from pydantic import validate_arguments @validate_arguments def input_user(user :

    User) -> None: pass external_data = { 'id': 1, 'name': 'パイソン 太郎', 'age': 19 } input_user(external_data) 有効範囲外の値 ValidationError
  7. pydanticの利用例〜Userクラスを返り値(辞書型)とする関数①〜 11 def output_user() -> dict: external_data = { 'id':

    1, 'name': 'パイソン 太郎', 'age': 20 } user = User.parse_obj(external_data) return user.dict() output_user() やりとりしやすい形式(辞書型)で出力 {'age': 20, 'id': 1, 'name': 'パイソン 太郎'}
  8. pydanticの利用例〜Userクラスを返り値(辞書型)とする関数②〜 12 def output_user() -> dict: external_data = { 'id':

    1, 'name': 'パイソン 太郎', 'age': 19 } user = User.parse_obj(external_data) return user.dict() output_user() 有効範囲外の値 ValidationError
  9. pydanticの利用例〜デコレーターによる詳細なバリデーションの実現〜 13 from pydantic import BaseModel, Field, validator import unicodedata

    class User(BaseModel): id: int name: str # 半角空白を含む(※前後以外) age: int = Field(ge=20) @validator("name") def check_contain_space(cls, v): if " " not in v.strip(): # 前後の半角空白を無視 raise ValueError("ensure this value contains spaces") return v.strip() # 前後の半角空白を削除 デコレーターによる詳細な バリデーションの実現も可能 (例:半角空白を含むかを判定)
  10. まとめ • 複数の部品によって構成されるシステムの開発 ◦ 部品:モジュール・クラス・メソッドなど ◦ 各部品が役割と責任を持ち連携 ◦ 課題①:入出力で扱うデータの定義がわからない(可読性の課題) ◦

    課題②:入出力で扱うデータが正しくない(堅牢性の課題) • 課題を解決する“pydantic” ◦ モデルを定義することでデータのバリデーションを実現するライブラリ ◦ 課題①:モデルの定義により把握が可能に(規約化) ◦ 課題②:定義に基づくバリデーションにより正しいデータのみが存在する状態に 14