FastAPI の簡単なサンプルを作る

結構、参考になる解説サイトがあるもので、
チュートリアル - ユーザーガイド - FastAPI
ここを見て、まずは必要最低限を書きます

import uvicorn
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def root():
    a = "sample"
    return {"hello": a}


@app.get("/view/{id}")
def view(id: int):
    # TODO view結果生成
    return {"viewid": f"{id}" }


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

これを起動すれば、
http://localhost:8000/
で動きます。
Swagger 書式のAPI定義は、http://localhost:8000/docs

ReDoc書式のAPI定義は、http://localhost:8000/redoc

で、開きます。このままではAPI定義書として説明が不十分なのと、
POST の列も書いておきたいので、以下のように追記します。

まずは、インポートするもの、、

from fastapi import FastAPI,Path,Query
from pydantic import BaseModel,Field
from typing import Union

FastAPIの他に、
 Path :URIのパスパラメータから取得する定義を記述する為に必要
 Query:クエリパラメータ定義を記述する為に必要
 BaseModel:レスポンスモデル、リクエストモデル定義を記述する為に必要
 Field:モデル定義内のフィールドプロパティ定義を記述する為に必要
 Union:モデル定義内のフィールドプロパティで省略可を記述する為に必要
これらを使います。
クエリパラメータの必須の書き方、、
クエリパラメータのデフォルトを書かなければ、required にはなる。

全体のサンプル
一通り見渡せた方が良いので、以下に書いてます。

import uvicorn
from fastapi import FastAPI,Path,Query
from pydantic import BaseModel,Field
from typing import Union

class ViewBody(BaseModel):
    viewid: int=Field(description="view実行したID")
    message: str=Field(description="メッセージ", default=None )
class QueryBody(BaseModel):
    id: int=Field(description="クエリ結果ID")
    title: str=Field(description="タイトル" )
class AddBody(BaseModel):
    status: int=Field(description="登録したID" )
class Item(BaseModel):
    name: str=Field(description="品名")
    price: int=Field(gt=100, description="価格")
    description: Union[str, None] = None
class Error400(BaseModel):
    errorMessage: str=Field("不正なリクエスト")
class Error401(BaseModel):
    errorMessage: str=Field("認証エラー")
class Error500(BaseModel):
    errorMessage: str=Field("システムエラー")

app = FastAPI();

@app.get("/")
def root():
    a = "sample"
    return {"hello": a}


@app.get("/view/{id}", response_model=ViewBody,
             responses={
                 401: {"model": Error401},
                 500: {"model": Error500}
             }
         )
def view(id: int=Path(gt=0, description="view対象のID")):
    # TODO view結果生成
    return {"viewid": id }


@app.get("/query", response_model=QueryBody,
             responses={
                 400: { "model": Error400 },
                 401: { "model": Error401 },
                 500: { "model": Error500 }
             }
         )
def query(id: int=Query(gt=0, description="クエリID"),
          subno: int=Query(gt=0, description="枝番号"),
          ops: str=Query(None, description="オプション")):
    # TODO クエリ結果生成
    answer = f"Test Query : {subno}"
    return {"id": id, "title": answer}


@app.post("/add", response_model=AddBody,
              responses={
                  400: {"model": Error400},
                  401: {"model": Error401},
                  500: {"model": Error500}
              }
          )
def add(item: Item):
    # TODO 追加登録実行して id をセット
    id = 10
    return {"status": id}


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

これの ReDoc の結果を参照してみる、→ http://localhost:8000/redoc
Swagger と ReDoc 、好みが分かれるところだろう。