pydanticでUnion型を使うときはLiteralと組み合わせるといい
チャットボットを実装しており、「ユーザーの過去のリクエスト内容をRedisに保存しておいて、必要に応じて参照してbotの返信に利用する」という実装をしています。具体的には以下のような仕様とプログラムです。
- ユーザーのリクエストのjsonを
Request
型にキャストして利用する - Redisでは、pydanticの型を
json
に変換して文字列として保存し、取り出すときにRequest
型にキャストする - 同時にそのjsonをログに出力する
from __future__ import annotations
from typing import Union, Optional
from typing_extensions import Literal
from .event import EventData
class Request(BaseModel):
user_id: str
session_id: str
command: Union[MessageCommand, ButtonCommand]
class MessageCommand(BaseModel):
"""自由文のメッセージが入力されたとき"""
type: Literal["message"]
message: Optional[str]
is_first: bool = False
class ButtonCommand(BaseModel):
"""ボタンを入力されたとき"""
type: Literal["button"]
event: Optional[EventData]
is_first: bool = False
Request.update_forward_refs()
当初、type
のプロパティを用意しておらず、Redisから取り出す際にButtonCommand
であるべきjsonが、誤って空のMessageCommand
としてキャストされてしまっていました。デフォルト値やOptional
を利用しているときは、間違ったjsonでもキャストできてしまいます。
それをtype
プロパティにLiteral
で固定の文字列を指定することで、確実に変換先を指定することができます。
参考
Author And Source
この問題について(pydanticでUnion型を使うときはLiteralと組み合わせるといい), 我々は、より多くの情報をここで見つけました https://qiita.com/ninomiyt/items/e40aaeb541bac0f2f6e3著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .