2
0

More than 1 year has passed since last update.

PydanticのモデルがPythonの予約語と被った時の対処

Last updated at Posted at 2022-01-26

みんな大好き、openapi-generator-cliで、python-fastapiジェネレータを使い、予約語と被るフィールドがあるモデルを生成した際、変な出力が出されたので、その修正策を考えました。

作ろうとしたAPIレスポンス

まず、今回作ろうとしているAPIはこのような型のデータを返します。あれ、defってなんとかできるんだっけ?と初めから不安でしたが、とりあえず生成。 (残念ながら自分で定義した仕様でないので従わざるを得ない..)

レスポンス型
{
  "query": "rating",
  "name": "#RATING_MIN",
  "def": 0,
  "min": 0,
  "max": 50,
  "step": 1,
  "display": "number"
}

実際のAPIのスキーマ

この型を返すAPIのスキーマを適当に定義してみます。
バリデーションに最低値が0以上と指定しておきましょう。
(すみませんめんどくさくなってしまったので、各自で定義してみてください...)

生成コマンド

そしてopenapi-generator-cliで生成してみます。

openapi-generator-cli generate -i test.yaml -g python-fastapi -o api_gen

生成したモデル

生成したモデルにはこのようなモデルが出てきました

src->models->search_slider_option.py(修正前)
class SearchSliderOption(BaseModel):
    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).

    Do not edit the class manually.

    SearchSliderOption - a model defined in OpenAPI

        query: The query of this SearchSliderOption.
        name: The name of this SearchSliderOption.
        type: The type of this SearchSliderOption.
        _def: The _def of this SearchSliderOption.
        min: The min of this SearchSliderOption.
        max: The max of this SearchSliderOption.
        step: The step of this SearchSliderOption.
        display: The display of this SearchSliderOption.
    """

    query: str
    name: str
    type: str
    _def: int
    min: int
    max: int
    step: int
    display: str

    @validator("def")
    def _def_min(cls, value):
        assert value >= 0
        return value

defは Pythonの予約語なので アンダースコアが接頭辞に追加されています。なるほど、ちゃんとやっている、と思ったのですがこの段階では、pydantic.errors.ConfigError を吐かれてしまい、動作させられませんでした。この原因はエイリアスが設定されていないってことだろうと思い、普通にPydanticのエイリアス設定方法を調べます。が、どの設定方法でもうまくいきませんでした。エイリアスを設定したらその時点で動くと思ったのですが...

どう解決するか

色々試したところ、そもそも変数名にアンダースコア入ってるのが悪いんじゃね?ってことに気づきました。そこで、_defdefault に変えてみたら、うまくいきました。

src->models->search_slider_option.py(修正後)
from pydantic import AnyUrl, BaseModel, EmailStr, Field, validator  # noqa: F401


class SearchSliderOption(BaseModel):
    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).

    Do not edit the class manually.

    SearchSliderOption - a model defined in OpenAPI

        query: The query of this SearchSliderOption.
        name: The name of this SearchSliderOption.
        type: The type of this SearchSliderOption.
        _def: The _def of this SearchSliderOption.
        min: The min of this SearchSliderOption.
        max: The max of this SearchSliderOption.
        step: The step of this SearchSliderOption.
        display: The display of this SearchSliderOption.
    """

    query: str
    name: str
    type: str
    default: int = Field(..., alias="def")
    min: int
    max: int
    step: int
    display: str

    @validator("default")
    def default_min(cls, value):
        assert value >= 0
        return value

まじか、そんなことあるのか となりましたが、まぁ動いたのでヨシです!

参考

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0