FastAPIでPythonのWebアプリケーションを開発する方法

FastAPIはPythonのWebアプリケーションフレームワークであり、高性能で堅牢なAPIを構築するためのツールセットを提供します。

インストール

pip install fastapi
pip install "uvicorn[standard]"

ファイルアップロード利用時は以下もインストールします。

pip install python-multipart

使用方法

appオブジェクトのデコレータ(@app.get@app.post)を使用して、ルーティングを定義します。引数にはURLパスを指定します。関数デコレータの下に書かれた関数が、そのルーティングに対応した実行関数となります。

main.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def get_root():
    return { "message": "Hello, world" }
#;

クエリパラメータ

@app.get("/with-param")
def get_with_param(sendvalue: int=0):
    return { "Receive Value": sendvalue }
#;

パスパラメータ

アクセスするURLにパラメータを埋め込みます。

@app.get("/test-process/{min}")
async def process_items(min: int):
    return { "param": min }
#;

パラメータのデフォルト値は、次のように記述できます。

async def process_items(min: int = 0):

しかし、この時、/test-processにアクセスしても404エラーが発生します。

パラメータなしで/test-processにアクセスするためには別のエンドポイントを追加します。

@app.get("/test-process/{min}")
async def process_items(min: int = 0):
    return { "param": min }
#;

@app.get("/test-process")
async def process_items_default():
    return { "param": 0 }
#;

リクエストボディ

下記はJSONで受け取る場合です。オプショナルなパラメータは Union[型, None] = Noneで定義します。

from fastapi import FastAPI
from pydantic import BaseModel
from typing import Union

class Item(BaseModel):
    name: str
    age: int
    tel: Union[str, None] = None
#;

app = FastAPI()

@app.post("/req-body")
def post_req_body(json: Item):
    return json
#;

レスポンス

画面については、別記事に記載予定です。

JSONを返す

@app.get("/json")
def get_json():
    dic = {
        "age": 20,
        "name": "hoge",
        "Country": "japan"
    }

    return dic
#;

ファイルを返す

from fastapi.responses import FileResponse

@app.get("/send-file")
def get_send_file():
    response = FileResponse(
                path = "ファイルパス",
                filename = "ダウンロードファイル名")
    return response
#;

CSVデータを返す

from fastapi.responses import Response

@app.get("/csv")
def get_csv():
    content = "q,w,e,r,t\r\na,s,d,f,g\r\nz,x,c,v,b"

    response = Response(content=content)
    response.headers["Content-Disposition"] = f"attachment; filename=sample.csv"
    response.media_type = "text/csv"
    return response
#;
CSVファイル
q,w,e,r,t
a,s,d,f,g
z,x,c,v,b

ストリーミングを返す

下記はJPEGデータを順番に送信し、MotionJPEGのように扱う方法です。

from fastapi.responses import StreamingResponse

def start_stream():
    while True:
        # Jpegデータをループ内で読み込む
        jpeg_bytes = "JPEGデータ"
        yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + jpeg_bytes + b'\r\n')
    #;
#;

@app.get("/get-image", response_class=StreamingResponse)
async def get_image():
    return StreamingResponse(start_stream(),
            media_type="multipart/x-mixed-replace; boundary=frame")
#;

エラーレスポンス

from fastapi import HTTPException

@app.get("/test-error")
def get_test_error():
    raise HTTPException(status_code=400, detail="Test Error")
#;

コマンドラインからの実行方法

上記、main.pyの場合、uvicorn main:appで実行します。

uvicorn main:app
INFO:     Started server process [13938]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
  • main - main.py
  • app - main.py内のappオブジェクト

上記実行後、http://127.0.0.1:8000にブラウザでアクセスすると結果が取得できます。

外部からのアクセス

上記では、127.0.0.1またはloclahostでしかアクセスできません。外部からアクセスするには、以下のようにコマンドを実行します。

uvicorn main:app --host 0.0.0.0

実行ファイルがサブディレクトリにある場合

上記main.pyが次のような構成の場合。

project_root/
|-- sub_dir/
    |-- main.py

project_rootから実行する場合は、コマンドを次のようにします。

uvicorn sub_dir.main:app --host 0.0.0.0

WSL2の場合

上記ではWSL2内コマンドip a show dev eth0のアドレスでしかアクセスできません。(同一PCからしかアクセスできない)
WindowsPCのIPアドレスで外部からアクセスするためには、Windows側でポートフォワード設定が必要です。

eth0のアドレスではアクセスできるが、localhostで接続できない場合

WSL2のWebサーバへlocalhost指定でアクセスするために、Windows側で次のファイルに以下の変更が必要です。
%USERPROFILE%/.wslconfig

[wsl2]
localhostForwarding=true

変更後、PowerShellで次のコマンドでWSL2を終了してから、WSL2を起動します。

wsl --shutdown

ポートの指定

デフォルトのポートは8000。変更したい場合は--portパラメータを指定する。

uvicorn main:app --host 0.0.0.0 --port 8080

Pythonコマンドでの実行

python3 ファイル名で実行したい場合は次のようにファイルに記述します。
import uvicornが必要です。

import uvicorn

// 処理

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)
このエントリーをはてなブックマークに追加
にほんブログ村 IT技術ブログへ

スポンサードリンク

関連コンテンツ

コメント

メールアドレスが公開されることはありません。 が付いている欄は必須項目です