概要
pythonの型ヒントを強化するパッケージ。
beartypeがバリデーションだけだったのに対して、こちらは変換なども行うことができる。
v1とv2があるらしいが、基本的にv2ベースでまとめていく。
- GitHub : https://github.com/pydantic/pydantic
- ドキュメント : https://pydantic.dev/docs/validation/latest/get-started/
- ドキュメント(日本語翻訳) : https://www.neko-neko-tech-tech.life/docs/pydantic/api/base_model/
インストール
組み込みパッケージではないので、別途インストールする必要あり。
pip install pydantic
簡単な利用例
BaseModel
クラス定義時にBaseModelを継承すると、pydanticの各種バリデートの仕組みを利用できるようになる。
class SimpleUser(BaseModel):
name: str
age: int
以下のように呼び出せる。
# 各フィールドを指定して呼び出す
SimpleUser(name="John", age=30)
# jsonオブジェクトで値を渡す
SimpleUser.model_validate({"name": "John", "age": 30})
# json文字列で値を渡す
SimpleUser.model_validate(json.dumps({"name": "John", "age": 30}))
intの値を文字列で渡した場合、自動でintに変換してくれる。
ただし、自動で変換できないような文字列の場合はエラーになる。
print(SimpleUser(name="John", age='30')) # name='John' age=30
print(SimpleUser(name="John", age='Invalid')) # エラー
なお、通常のフィールドを指定して初期化の場合は、IDE上でワーニングを表示してくれるが、jsonオブジェクトやjson文字列による初期化の場合は、わーニングが表示されない。
SimpleUser(name="John", age='30') # IDE上でワーニングあり
SimpleUser.model_validate({"name": "John", "age": "30"}) # ワーニングなし
RootModel
BaseModelの特殊ケース。
実体としてはBaseModelを継承して定義されている。
利用方法としては、BaseModelとほぼ同じであるが、RootModelはフィールド定義ができない。
クラスの初期化時に渡されるオブジェクトを格納するフィールドのみ持つクラスとなる。
class CustomConfig(RootModel[dict[str, Any]]):
def get_version(self) -> Optional[str]:
return self.root.get("version")
config = CustomConfig({"flag": True, "version": "1.0"})
print(config.get_version()) # "1.0"
print(config.root) # 入力したオブジェクトが表示される
field_validator
フィールドに対してバリデーションを付与できる。
以下はnameにバリデーションを付与した例。
class User(BaseModel):
name: str
age: int
# modeにはbefore, afterがある
# before : 変換前に呼ばれる
# after : 変換後に呼ばれる (str -> int など)
# wrap : (cls, v, info)の3つの引数を受け取る。infoで検証関数の情報を取得できる
@field_validator('name', mode='before')
def name_validator(cls, v):
if len(v) < 1 or len(v) > 4:
raise ValueError('must be between 1 and 4 characters')
return v
以下のように実行時にエラーになる。
なお、IDE上のワーニングなどは表示されない。
User(name="John", age=30) # OK
User(name="John2nd", age=30) # エラー
dataclass
pythonの組み込みAPIにdataclassデコレータが存在するが、pydanticにも同名のデコレータが存在する。
機能的にはほぼ同一であるが、標準のdataclassの機能に加えて、バリデーション機能が追加されている。
from pydantic.dataclasses import dataclass
@dataclass
class SimpleUser:
name: str
age: int
# BaseModelの場合と同様に、"30"が30として自動で変換される
print(SimpleUser(name="John", age="30")) # name='John' age=30
なお、標準のdataclassの場合は、型が間違っていてもそのままインスタンスが作成される。
from dataclasses import dataclass
@dataclass
class PythonUser:
name: str
age: int
# ageは文字列から変換されずそのまま入る
print(PythonUser(name="John", age="30")) # name='John' name='30'
TypeAdapter
任意の型に対する検証、正規化などの機能を提供する。
以下の例では、元データの一部に文字列となっている箇所があるが、TypeAdapterを通してintに正規化されている。
ty = TypeAdapter(list[int])
print(ty.validate_python(['1', 2, '3'])) # [1, 2, 3]
その他
その他のAPIについては、ドキュメントを参照。
終わりに
pydanticについて調査したので簡単にまとめました。
beartypeと同様に、pythonの通常の型ヒントで十分なケースがほとんどだと思うので、導入する際には、pydanticで何を実現したいのか明確にしておく必要があるかと思います。
また、データの訂正機能がある点を考慮すると、データクレンジングをプログラム側で行うケースなどでは有用なのではないかと思いました。