1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FastAPIのOpenAPIバージョンをpyproject.tomlから取得する

Posted at

課題

FastAPIでAPIサーバーを作っている。

FastAPIは関数の引数や戻り値の型情報を読み取ってOpenAPI(旧Swagger)形式のドキュメントを作ってくれる。

OpenAPIには今のAPIのバージョンを設定するフィールドがあり、ここでAPIのバージョンを管理することができる。
もちろんハードコーディングで管理してもいいのだが、今回はパッケージマネージャーにPoetryを使っているので、 pyproject.toml 内の [tools.poetry] セクションの version を動的に読み取るようにすると綺麗に管理できるような気がした。

pyproject.toml
[tool.poetry]
name = "my_api_server"  # <- ついでにこれも表示させたい
version = "12.8.9"  # <- これをOpenAPIドキュメントに表示させたい
description = "私のAPIサーバーです。"  # <- ついでにこれも表示させたい
authors = ["que9 <example@example.com>"]

...

解決方法

愚直に実装した。なお、TOMLファイルの読み込みには toml パッケージを採用した。

  1. poetry add toml を実行し、toml パッケージをインストールする
  2. main.py に以下を仕込む
main.py
import os
from typing import Any, Dict

import toml
from fastapi import FastAPI
from fastapi.openapi.utils import get_openapi

app = FastAPI()

def custom_openapi():
    if app.openapi_schema:
        return app.openapi_schema

    assert os.path.exists("pyproject.toml")

    with open("pyproject.toml") as f: # ... ③-1
        pyproject_toml = toml.load(f) # ... ③-1
        poetry: Dict[str, Any] = pyproject_toml["tool"]["poetry"]
        title: str = poetry["name"]
        version: str = poetry["version"] # ... ③-2
        description: str = poetry["description"]

    app.openapi_schema = get_openapi( 
        title=title,
        version=version, # ... ②
        description=description,
        routes=app.routes,
    )
    return app.openapi_schema

app.openapi = custom_openapi # ... ①


@app.get("/test")
def test():
    return "success"

一応解説すると、 app.openapi にOpenAPIのスキーマ情報を取得する関数 custom_openapi を定義している(①)。
OpenAPIのスキーマ情報は fastapi.openapi.utils.get_openapi に適当に引数を設定すると取得できる(②)。
引数に設定する値はtomlパッケージを使って pyproject.toml から読み込んでいる(③-1)。
[tool.poetry]version を参照するためには pyproject["tool"]["poetry"]["version"] のようにしてアクセスできる
今回はバージョンの他にも namedescription もスキーマ情報として設定したかったので、
pyproject["tool"]["poetry"] を一時変数に代入してから取得するようにしている(③-2)。

結果

こんな感じ。

/docsの表示

スクリーンショット 2021-08-05 20.42.44.png

/redocの表示

スクリーンショット 2021-08-05 20.43.07.png

main.py を書き換える前はバージョンが0.1.0だったが、書き換えた後は pyproject.toml 記載の値になった。
ついでにAPIの名称や説明文も pyproject.toml 記載の値になった。よしよし。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?