はじめに
Pydanticについて解説します。
半分自分用のメモです。よろしくお願いします。
Pydanticでできること①型チェック
Pydanticは型ヒントをもとに自動で値をチェックしてくれる便利なライブラリです。
- 型チェック
- モデルの入れ子
- エラーがあれば検出
- 正常なら Python オブジェクトとして返す
Pydanticを使えば上記を自動で処理されます。
from pydantic import BaseModel
from typing import List
branch = {
"branch_name" : "大阪",
"staff": [
{"number": "1","name":"佐藤","夜勤可能":True},
{"number": 2,"name":"田中","夜勤可能":False},
{"number": 3,"name":"山本","夜勤可能":True}
]
}
class Staff(BaseModel):
number: int
name : str
夜勤可能 : bool
class Branch(BaseModel):
branch_name : str
staff : List[Staff]
model = Branch(**branch)
print(model)
出力結果
branch_name='大阪' staff=[Staff(number=1, name='佐藤', 夜勤可能=True), Staff(number=2, name='田中', 夜勤可能=False), Staff(number=3, name='山本', 夜勤可能=True)]
str型の”1″をint型の1に型変換して出力してくれました。
続いて、型の定義を変更するとどうなるでしょうか。
from pydantic import BaseModel
from typing import List
branch = {
"branch_name" : "大阪",
"staff": [
{"number": "1","name":"佐藤","夜勤可能":True},
{"number": 2,"name":"田中","夜勤可能":False},
{"number": 3,"name":"山本","夜勤可能":True}
]
}
class Staff(BaseModel):
number: int
name : int
夜勤可能 : bool
class Branch(BaseModel):
branch_name : str
staff : List[Staff]
model = Branch(**branch)
print(model)
出力結果
validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
pydantic_core._pydantic_core.ValidationError: 3 validation errors for Branch
staff.0.name
Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='佐藤', input_type=str]
For further information visit https://errors.pydantic.dev/2.12/v/int_parsing
staff.1.name
Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='田中', input_type=str]
For further information visit https://errors.pydantic.dev/2.12/v/int_parsing
staff.2.name
Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='山本', input_type=str]
For further information visit https://errors.pydantic.dev/2.12/v/int_parsing
nameの入力値はint型で入れてください!とエラーが表示されましたね。
型チェックが行われているのが確認できました。
Pydanticでできること②環境変数の自動読込み
Python では、環境変数は os.environ でアクセスできます。
import os
#os.environ.get("VAR")で値を取り出せる
app_name = os.environ.get("APP_NAME")
debug = os.environ.get("DEBUG")
port = os.environ.get("PORT")
print(app_name, debug, port)
これだと、文字列しか返ってこないですね。
ですので型変換は自分で行う必要があります。こんな感じで↓
port = int(os.environ.get("PORT", 8000)) # int に変換
debug = os.environ.get("DEBUG", "False") == "True" # bool に変換
Pydanticには環境変数から値を読み込む仕組みが標準であります。
サンプルのファイル構成:
pydantic/
├─ .env
├─ pyproject.toml
├─ poetry.lock
└─ my_project/
├─ __init__.py
├─ settings.py
└─ main2.py
.env
.env は テキストファイルに環境変数の値をまとめたものです。
APP_NAME="My Pydantic App"
DEBUG=True
PORT=9000
setting.py
from pydantic_settings import BaseSettings
from pathlib import Path
class Settings(BaseSettings):
app_name: str
debug: bool = False
port: int = 8000
model_config = {
"env_file": str(Path(__file__).parent.parent / ".env"), #どのディレクトリから実行しても .env を正しく読み込めるようにした
"env_file_encoding": "utf-8",
}
main.py
from settings import Settings
def main():
settings = Settings()
print("App Name:", settings.app_name)
print("Debug:", settings.debug)
print("Port:", settings.port)
if __name__ == "__main__":
main()
処理の流れ:
①main.py 実行
②settings.py が import
③Settings クラス定義(model_config 読み込み)
④settings = Settings() ← インスタンス化
⑤.env ファイル読み込み → 型変換 → バリデーション
⑥settings の属性に値がセットされる
⑦main.py の print で値を表示
実行結果:
App Name: My Pydantic App
Debug: True
Port: 9000
🪐おまけ .env と export の違い
| 方法 | 説明 | 永続性 |
|---|---|---|
export VAR=VALUE | シェルで環境変数を設定 | ターミナルを閉じると消える |
.env ファイル | 環境変数をテキストにまとめる | ファイルがある限り使える |
PydanticのBaseSettingsは両方サポートされています。
.env があれば読み込み、環境変数があればそちらが優先されます。
ありがとうございました✨
