【Termux+Python】Pydanticを導入してみた

Pydantic は、Python用のデータバリデーションおよびデータモデルライブラリです。Pythonの型ヒント (type hints) を活用して、データのバリデーションや変換を自動で行います。
Pydanticを導入することにより、下記の利点があります。
- バリデーションの自動化型ヒントを使うだけで、詳細なバリデーション処理を簡単に定義できる。
- 可読性の向上データモデルが明確になり、コードの可読性が高まる。
- エラー対応が楽になるバリデーションエラーが詳細に表示され、デバッグしやすい。
- API開発が効率化FastAPIなどと組み合わせると、エンドポイントのパラメータバリデーションやスキーマ生成が簡単。
- 型変換が便利データベースや外部APIから取得したデータの変換が容易。
Pydanticの導入方法
- Rustをインストールする
pydantic v2は高速化のために一部をRustで実装しており、デフォルトでビルド時にRustコンパイラを要求します。したがって、Pydanticをインストールする前にRustを導入します。
$ pkg update
$ pkg upgrade
$ pip install rust
$ pip install pydantic
- Pydanticをインストールします。
$ pip install pydantic
$ pip install pydantic-settings
$ pip install python-dotenv
Pydanticのインストールにはかなりの時間がかかります。
フリーズしているようにも見えますので、コーヒーでも飲みながら気長に待ちましょう。
なお、.envファイルを扱う場合は、環境変数や設定ファイルから設定情報を管理・読み込むためのpydantic-settingsもインストールします。
pydantic-settings
.env
ファイルや環境変数、設定ファイルから設定を読み込む。- デフォルト値や必須設定の定義。
- Pydanticのバリデーション機能を使って設定の型チェック。
- Pydanticを導入したPythonのコードを書いてみる。
インストールが終わったら、早速Pydanticを導入したPythonコードを書いてみます。
次のコードは、スマホからGhostに記事をアップロードする際の認証トークンを作成するPythonのコードです。
# jwt_generator.py
import jwt
from datetime import datetime as date
from pydantic import BaseModel, ValidationError, SecretStr, Field
from pydantic_settings import BaseSettings, SettingsConfigDict
import sys
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file="~/.termux/tasker/.env", regex_engine='python-re')
ADMIN_API_KEY: str = Field(pattern=r"^.*:.*$")
TOKEN_EXPIRY: int = 5 * 60 # トークンの有効期限(秒)
# トークン生成用のペイロードモデル
class TokenPayload(BaseModel):
iat: int
exp: int
aud: str = '/admin/'
def generate_jwt(settings: Settings) -> str:
try:
client_id, secret = settings.ADMIN_API_KEY.split(':')
except ValueError:
raise ValueError("Invalid ADMIN_API_KEY format. Expected format: 'xxxx:yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'")
# print('client_id:'+client_id)
iat = int(date.now().timestamp())
header = {'alg': 'HS256', 'typ': 'JWT', 'kid': client_id}
payload = TokenPayload(
iat=iat,
exp=iat + settings.TOKEN_EXPIRY
).model_dump()
token = jwt.encode(payload, bytes.fromhex(secret), algorithm='HS256', headers=header)
return token
if __name__ == "__main__":
try:
settings = Settings()
token = generate_jwt(settings)
# sys.stdout.write(token)
file_path = "/storage/emulated/0/Download/jwt_token.txt"
with open(file_path, "w") as f:
f.write(token)
except ValidationError as e:
sys.stderr.write(f"Configuration error: {e}\n")
except ValueError as e:
sys.stderr.write(f"Error: {e}\n")