ITで遊ぶ

FastAPIの最低限の勉強

ライブラリーの持ち込みは

pip install fastapi uvicorn

サンプルの最小限っぽいサンプルコード

# api.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

# 別ポートのHTMLから呼べるようにCORSを許可
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.get("/hello")
def hello():
    return {"message": "Hello FastAPI"}

@app.get("/add")
def add(a: int, b: int):
    return {"result": a + b}

if __name__ == "__main__":
    import uvicorn
    # 192.168.1.16:8001 で待ち受け
    uvicorn.run(app, host="0.0.0.0", port=8001)

これを起動する方法は

python fsatest.py

ブラウザー側

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>FastAPI test</title>
</head>
<body>
<h1>FastAPI Test</h1>
<button onclick="callApi()">API call</button>
<pre id="result"></pre>
<script>
async function callApi() {
const r = await fetch("http://localhost:8001/add?a=2&b=3");
const data = await r.json();
document.getElementById("result").textContent =
JSON.stringify(data, null, 2);
}
</script>
</body>
</html>

アプリ本体について

FastAPIは簡単にかけるけれども、メカニズムはかなりややこしい。
@で始まるデコレーターを見てみよう。これは実は関数を登録しているだけ。たとえば

@app.get("/hello")
async def hello():
  return {"msg": "hello"}

は/helloがきたら 関数helloを呼ぶ。呼び出し方はgetというルーティングリストを作っている。

もう一点重要なことは、FastAPIはPython変数の型情報に応じた処理をおこなっていること。

@app.get("/add")
def add(1:int, b: int):
  return a+b

があれば変数a, bはintと理解します。
そして

  • query paramtger
  • 型変換
  • バリデーション
  • OpenAPI仕様
  • Swagger UI

を生成してくれる。

uvicornについて

ASGIサーバーというものがあります。uvicorn, gunicorn, hypercornなどがあります。
WebServerはFastAPIを直接起動しないのです。WebサーバーとしてLighttpdを使うと次のようになります。

ブラウザー → lighttpd → uvicorn → FastAPIアプリ

という流れです。
uvicornはhttp通信、ソケット、非同期処理を行い、FastAPIは関数を呼ぶアプリです。
この非同期処理がキモで、従来のWSGI(FlaskやDjangoが使っている)では実現されていません。

なお、lighttpdの中では上のプログラムの場合、


proxy.server =(
    "/api" => (
        ("host" => "127.0.0.1", "port" => 8001)
    )
}

となります。

関連記事

  1. ソフトウェアは進歩し続けなけりゃならんのか?

  2. Windowsパソコンの買い替え/アップデート

  3. 製品を作るおじさんの独り言

  4. IEEE754 十進浮動小数点演算

  5. python 正規表現で文字列判定

  6. CodeIgniter 別のViewの書き方

  7. PHP, Python, Ruby, バランス

  8. 静的HTMLに他HTMLを読み込む方法