FastAPIでPythonのWebアプリケーションを開発する方法
FastAPIはPythonのWebアプリケーションフレームワークであり、高性能で堅牢なAPIを構築するためのツールセットを提供します。
インストール
pip install fastapi
pip install "uvicorn[standard]"
ファイルアップロード利用時は以下もインストールします。
pip install python-multipart
使用方法
appオブジェクトのデコレータ(@app.get
や@app.post
)を使用して、ルーティングを定義します。引数にはURLパスを指定します。関数デコレータの下に書かれた関数が、そのルーティングに対応した実行関数となります。
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
#;
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)