LoginSignup
2
0

More than 1 year has passed since last update.

APIドキュメントから生成したFastApiスタブをPysenに怒られないようにするまで

Last updated at Posted at 2022-01-26

以前はFlaskを使ってゆるい型もないゆるゆるフワフワしたAPIを作って居たものです。
しかしながら、最近は型の概念がいかに素晴らしいかというのをTypeScriptやらGolangやらで体感したので、たとえPythonであっても、しっかりした型でいい感じのコードを書きたくなりました。

開発環境

  • Poetry+Pysen
    • これが今どきの最新っぽい雰囲気でおすすめされてたので使います
  • openapi-generator-cli
    • 別に何で生成してもいいと思いますが、以前から何度か使っていて慣れているので使う
  • Stoplight
    • 初めからStoplight使って居るので、無いとやってられない、もはや手書きでは書けない

1 ドキュメントを作る

Stoplightでガリガリ書きます

2 Python-templeteを使い PysenとPoetry入ったプロジェクトを生成

で作ったあと、git clone してくる。
(非常に助かりましたありがとうございます)

3 openapi-generator-cliで ドキュメントからスタブ生成

cloneしたプロジェクトのsrcフォルダ内でスタブを作る。

npm install -g openapi-generator-cli
openapi-generator-cli generate -g python-fastapi -i server.yaml -o api_gen

4 生成したフォルダを調整

個人的にsrcフォルダ内直下に入って欲しい。なのでまずは VSCodeのファイル内検索で、from openapi_server.modelsfrom src.modelsに一括置き換えする。
そして openapi_serverフォルダの中身を全て 1階層上に移動する。

5 テストの返り型を指定

openapi-generator-cliで生成したテストは 返り値型が付いていないので
(client: TestClient):(client: TestClient) -> None: に一括置き換えする

6 paramsの型TupleではなくDictにする

そのままでは testsのclient.requestのparamsはtyping.MutableMapping[str, str]、つまりDict型を要求するにも関わらずparamsがTupleとして投げられるため、mypyが怒る。(実際には内部で上手いことやってくれるようだが。)
[("localization", "en"), ("page", 1), ("keywords", "test")]dict([("localization", "en"), ("page", 1), ("keywords", "test"))として一括置き換えして、明示的にDict型にする

7 paramsにValueに型が無いのでStrにする

先程触れたように testsのclient.requestのparamsはtyping.MutableMapping[str, str] であるため
paramsを Dict[str, str]にする。そのため、params =params: Dict[str,str] に置き換えて("page", 1)("page", "1")に置き換える。これでtestsフォルダのフォーマットは完了。poetry run pysen run formatしてpoetry run pysen run lintして問題なければCommit

8 apisのrouterに付いている Dependsをすべて 外してインポートするようにする。

Pythonの関数のデフォルト引数は、読み込まれたタイミングで一度だけ実装される。この仕様をしらずにあとから関数を実行してトラブルになる可能性があるため、デフォルト引数に関数を与えるとPEPに怒られる。
これを回避するには、共通するDependsを全て 別ファイルに書き出してしまえば良い。
詳細は省くが、いい感じに置き換えを使う。

9 横に長過ぎる説明を改行

OpenAPIドキュメントで書いてあるコメントが丁寧すぎる場合、flake8で指定してある88文字を大幅に超えることがある。その場合は改行を入れる。

10 モデル確認

ちゃんと生成されていればここまでで動くはずだが、上手く行かない場合は、複雑なモデルの生成に失敗している可能性がある。modelsフォルダの中のモデルを眺めてみて、おかしな生成があれば修正する。

11 完了

poetry run pysen run formatして
poetry run pysen run lint

isort .......... OK (2.01 sec)
black .......... OK (3.82 sec)
flake8 .......... OK (4.04 sec)
mypy .......... OK (17.52 sec)

というように、4人みんなにOKを貰えたら合格、CommitしてPush。

参考

実際作っているプロジェクト

テンプレートの解説ページ

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