メインコンテンツへスキップ

Pydanticで定義したクエリパラメータをFastAPIのドキュメントに反映する

·☕4分
#テック系 #Python #FastAPI #Pydantic
Rakuichi
著者
Rakuichi
ヴィッセルサポのIT屋
目次

タイトルの通り、FastAPIで自動生成されるOpenAPIドキュメント(Swagger)内で、Pydanticで定義したクラスをDependsしたクエリパラメータに対して、情報(説明文)をつける方法について紹介します。
※途中で触れますが、今回の解決方法はその場しのぎ的で奇麗な形ではありません

これからの説明では、単純にクエリパラメータとして受け取った文字列(名前)を、挨拶文にして返すAPIを例に見ていきます。(「Taro」を受け取って「Hello Taro!」を返す)

手っ取り早く実装例を見に行く

Pydanticモデルを利用しない場合
#

Pydanticを利用せずにFastAPIのみで完結させる場合は、簡単にドキュメントへ説明文を反映させることができます。

シンプルな定義
#

まずは、最低限の実装で確認してみます。こちらの方法では、ドキュメントに説明文をつけることはできません。

from fastapi import FastAPI

app = FastAPI()


@app.get("/hello")
async def hello(name: str):
    return {"message": f"Hello {name}!"}

この状態でドキュメントを確認してみます。説明文はありません。変数名で伝わるので、必要ないと考えることもできます。

シンプルな定義
シンプルな定義

Queryを使った定義
#

fastapiからQueryをインポートして、クエリパラメータの説明を加えていきます。Queryは様々なパラメータを持っており、制約(文字数制限等)を加えることもできます。今回は、あくまでドキュメントに情報を加えるだけなので、制約などについては触れません。詳しく見たい方は公式ドキュメントをご覧ください。

公式ドキュメント:https://fastapi.tiangolo.com/ja/tutorial/query-params-str-validations/

OpenAPIドキュメントに、対象クエリにどのようなものを入れるのか、説明を加えたいと思います。

from fastapi import FastAPI, Query


app = FastAPI()


@app.get("/hello")
async def hello(name: str = Query(description="名前を入れてください")):
    return {"message": f"Hello {name}!"}

ドキュメントを見てみましょう。

Queryを使った定義
Queryを使った定義

descriptionを加えることでドキュメントに説明が記載されました。

Pydanticを利用する場合
#

FastAPIでPydanticモデルを使用する時は、基本的にリクエストボディのデータを定義する場合になります。公式ドキュメントでは以下のように書かれています。

リクエスト ボディを宣言するために Pydantic モデルを使用します。そして、その全てのパワーとメリットを利用します。 https://fastapi.tiangolo.com/ja/tutorial/body/

クエリパラメータにPydanticモデルを適応する場合は、Depends()を利用します。こちらの方法はQiitaでも共有されています。

FastAPIでクエリパラメータの指定にPydanticのModelを使う - Qiita

今回の例では以下のようになります。引数queryHelloInオブジェクトが代入されるので、受け取った文字列を利用する場合はquery.nameとします。

HelloIn内に複数の変数を定義することで、複数のクエリを受け取ることも可能です。
from fastapi import Depends, FastAPI
from pydantic import BaseModel


app = FastAPI()


class HelloIn(BaseModel):
    name: str


@app.get("/hello")
async def hello(query: HelloIn = Depends()):
    return {"message": f"Hello {query.name}!"}

この場合のドキュメントは以下のようになります。

Pydanticを用いた定義
Pydanticを用いた定義

続いてPydanticを使いつつ、ドキュメントに説明文を反映していきたいと思います。感覚的には、HelloIn内のname: strname: str = Query(description="名前を入れてください")にすれば良い気がしたのですが、これはうまく反映されませんでした。

こちらに関して調べていたところ、FastAPIのリポジトリにイシューがあがっていました↓

Query parameters from Depends do not show description in docs · Issue #4700 · tiangolo/fastapi

今回紹介する方法はこのイシュー内でコメントされている方法になりますが、「I think there should be a better solution for this issue(この問題に対するより良い解決策があるはずです)」と書かれているので、他にいい方法があるかもしれません。

対処としては、以下のようにFieldQueryで2重にすれば良いです。ただ、issueを見ていても「やってみたらうまくいきました!」という書き方なので、TIPS的な認識で利用しています。

from fastapi import Depends, FastAPI, Query
from pydantic import BaseModel, Field


app = FastAPI()


class HelloIn(BaseModel):
    name: str = Field(Query(description="名前を入れてください"))
    # FieldでなくてQueryでもよい↓
    # name: str = Query(Query(description="名前を入れてください"))


@app.get("/hello")
async def hello(query: HelloIn = Depends()):
    return {"message": f"Hello {query.name}!"}

以下のように、ドキュメントに説明文が反映されています。

Pydanticを利用してドキュメントにも反映
Pydanticを利用してドキュメントにも反映

スポンサードリンク

Related

FastAPI×Streamlitでアプリ開発(Getリクエスト)
·☕6分
#テック系 #Python #FastAPI #Pydantic #Streamlit
APSchedulerを用いてFastAPIでジョブの定期実行
·☕5分
#テック系 #Python #FastAPI #APScheduler
FastAPIのファイル構成
·☕4分
#テック系 #Python #FastAPI
FastAPI × MKDocs ( × Docker )でAPIサーバとドキュメントペー …
·☕6分
#テック系 #Python #Pipenv #FastAPI #Docker #MKDocs