Pydanticで定義したクエリパラメータをFastAPIのドキュメントに反映する
目次
タイトルの通り、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}!"}
ドキュメントを見てみましょう。
description
を加えることでドキュメントに説明が記載されました。
Pydanticを利用する場合#
FastAPIでPydanticモデルを使用する時は、基本的にリクエストボディのデータを定義する場合になります。公式ドキュメントでは以下のように書かれています。
リクエスト ボディを宣言するために Pydantic モデルを使用します。そして、その全てのパワーとメリットを利用します。 https://fastapi.tiangolo.com/ja/tutorial/body/
クエリパラメータにPydanticモデルを適応する場合は、Depends()
を利用します。こちらの方法はQiitaでも共有されています。
FastAPIでクエリパラメータの指定にPydanticのModelを使う - Qiita
今回の例では以下のようになります。引数query
にHelloIn
オブジェクトが代入されるので、受け取った文字列を利用する場合は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を使いつつ、ドキュメントに説明文を反映していきたいと思います。感覚的には、HelloIn
内のname: str
をname: 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(この問題に対するより良い解決策があるはずです)」と書かれているので、他にいい方法があるかもしれません。
対処としては、以下のようにField
やQuery
で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}!"}
以下のように、ドキュメントに説明文が反映されています。