#author("2025-05-19T08:54:57+09:00","","")
#author("2025-05-30T04:51:38+09:00","","")
#mynavi()
#setlinebreak(on);
#mydateinfo(2024-10-06, 2025-05-19)


* 目次 [#k1925e13]
#contents
- 参考
-- ドキュメント: https://fastapi.tiangolo.com/ja/
-- ソースコード: https://github.com/fastapi/fastapi


* 概要 [#t207b1a8]

Python の Webフレームワーク。

以下、公式より引用 ( https://fastapi.tiangolo.com/ja/ )
#html(<div style="border: 1px solid #333; padding: 2px 10px 8px 10px; background: #eee;">)
高速: NodeJS や Go 並みのとても高いパフォーマンス (Starlette と Pydantic のおかげです)。 最も高速な Python フレームワークの一つです。
高速なコーディング: 開発速度を約 200%~300%向上させます。

- 少ないバグ: 開発者起因のヒューマンエラーを約 40%削減します。
- 直感的: 素晴らしいエディタのサポートや オートコンプリート。 デバッグ時間を削減します。
- 簡単: 簡単に利用、習得できるようにデザインされています。ドキュメントを読む時間を削減します。
- 短い: コードの重複を最小限にしています。各パラメータからの複数の機能。少ないバグ。
- 堅牢性: 自動対話ドキュメントを使用して、本番環境で使用できるコードを取得します。
- Standards-based: API のオープンスタンダードに基づいており、完全に互換性があります
#html(</div>)

「NodeJS や Go 並みのとても高いパフォーマンス」というのは本当か。
個人的には、ルーティングに関しては、そこそこのパフォーマンスは出せるかもしれないが、
ビジネスロジックをゴリゴリ書く場合、限界があるのではないかと推測。(検証が必要)

* インストール [#ia24a076]

#myterm2(){{
pip install fastapi
}}

本番環境ではASGI サーバーが必要(以下では Uvicorn を使用)
#myterm2(){{
pip install "uvicorn[standard]"
}}

* サンプル [#j09557f7]

#mycode2(){{
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}
}}


* 起動 [#ne05ba9e]

#myterm2(){{
uvicorn main:app --reload
}}

尚、以下のURLでAPIドキュメントを表示可能。
http://127.0.0.1:8000/docs  ( Swagger UI )
http://127.0.0.1:8000/redoc ( ReDoc )

* ルーティング等 [#ld695e0a]

- デコレータを使用してルーティングが可能
- クエリ文字列はメソッド引数から取得可能
- POST/PUT 等の入力データは BaseModel を継承したclassにマッピングして取得可能
- POST/PUT 等の入力データは pydantic.BaseModel を継承したclassにマッピングして取得可能
- fastapi.responses モジュールの各クラス(JSONResponse等)を使用して任意のレスポンス/ステータスを返却する事が可能

例)
#mycode2(){{
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from pydantic import BaseModel, Field

app = FastAPI()


# 動作確認用
class DataHolder:
    items = [ 
        {"item_id": "item01", "item_name": "アイテム01", "description": "説明01"},
        {"item_id": "item02", "item_name": "アイテム02", "description": "説明02"},
        {"item_id": "item03", "item_name": "アイテム03", "description": "説明03"},
    ]


class Item(BaseModel):
    item_id: str 
    item_name: str 
    description: str | None = None


@app.get("/")
def root():
    return {"message": "this is root"}


@app.get("/items")
def read_items(item_name: str = None):    # メソッド引数でクエリ文字列の取得が可能
    if item_name:
        return [i for i in items if i["item_name"] == item_name]
    return DataHolder.items


@app.get("/items/{item_id}")              # PATHパラメータは {項目名} で取得可能
def read_item(item_id):
    matched = [i for i in DataHolder.items if i["item_id"] == item_id]
    if matched:
        return matched[0]
    return JSONResponse(status_code=404, content={"message": "該当データなし"})


@app.post("/items", status_code=201)      # デフォルトのステータス宣言
def new_item(new_item: Item):             # BaseModelを継承したclassで入力データの取得が可能
    if len([i for i in DataHolder.items if i["item_id"] == new_item.item_id]) > 0:
        return JSONResponse(status_code=400, content={"message": "既に登録されています"})  # 任意のステータスを返却する場合
    DataHolder.items.append(new_item.dict())
    return new_item


@app.put("/items/{item_id}")
def update_item(item_id: str, item: Item):
    if len([i for i in DataHolder.items if i["item_id"] == item_id]) == 0:
        return JSONResponse(status_code=404, content={"message": "該当データなし"})
    upd_item = { "item_id": item_id, "item_name": item.item_name, "description": item.description }
    DataHolder.items = [upd_item if i["item_id"] == item_id else i for i in DataHolder.items]
    return {"message": "updated"}


@app.delete("/items/{item_id}")
def delete_item(item_id: str):
    if len([i for i in DataHolder.items if i["item_id"] == item_id]) == 0:
        return JSONResponse(status_code=404, content={"message": "該当データなし"})
    DataHolder.items = [i for i in DataHolder.items if i["item_id"] != item_id]
    return {"message": "deleted"}
}}

#TODO

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS