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

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

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

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

Avatar for Daiki Katsuragawa

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