Anaconda環境にFastAPIをインストールする

2023年6月10日土曜日

FastAPI Python

t f B! P L

FastAPIはPythonのWebフレームワークの1つで、Flaskのような軽量でパフォーマンスが早いことが特徴です。また、WSGIの後継であるASGIにも対応しているのも特徴の1つです。

この記事では、Anaconda環境でFastAPIをインストール・実行する方法を解説します。

スポンサーリンク

Anaconda仮想環境の作成

FastAPIアプリ用に、新しくAnacondaの仮想環境を作成します。既存の仮想環境に作る場合は、この作業は不要です。今回は「fast-api」という名前で仮想環境を作成し、Pythonのバージョンは「3.11」にしました。

conda create -n fast-api python=3.11

作成した仮想環境をアクティブにします。

conda activate fast-api

conda-forge チャンネルの追加

FastAPIは、Anacondaのデフォルトチャンネルではなく、conda-forge チャンネル登録されているので、自分のAnaconda環境にまだ conda-forge チャンネルを追加していない場合は、次のコマンドで追加しておこう。

$ conda config --append channels conda-forge
$ conda config --get channels

--add channels 'conda-forge'   # lowest priority
--add channels 'defaults'   # highest priority

FastAPI のインストール

「FastAPI」と、ASGIサーバーとして使う「Uvicorn」をインストールする。

$ conda install -c conda-forge fastapi uvicorn

ASGIサーバーとは?

ちょっと余談ですが、ASGIサーバーはPythonの非同期サーバーゲートウェイインターフェースです。HTTP、WebSocket、ロングポーリング等の非同期通信プロトコルをサポートし、効率的なWebアプリケーションを実現する機能です。

スポンサーリンク

簡単な GET API を作る

インストールできたら、HTTP GETのリクエストで「Hello World」の文字をJSON形式で返す、簡単な APIを作って動きを確認します。ソースコードを格納する適当なディクトリを作成し、次の内容のコードを main.pyとして保存します。

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

ファイルを保存したら、次のコマンドで起動します。 ```bash $ uvicorn main:app --reload ```

curl で作成した API にアクセスしてみましょう。

$ curl http://127.0.0.1:8000/
{"message":"Hello World"}

対話的APIドキュメント

ブラウザで http://127.0.0.1:8000/docs にアクセスすると、GUI で対話的API にアクセスできるツールが表示されます。

Root の URL を選択し、Executeボタンを押してAPIを実行します。結果に「Hello World」と表示されれば成功です。

スポンサーリンク

パラメータを受け取ろう

パスパラメータや、クエリパラメータを受け取ってみましょう。

パスパラメータ

パスパラメータは、@app.get(...) の中に、Python のフォーマット文字列と同じような方法で定義します。 例えば、ユーザーIDをパスパラメータとして受け取る場合は、次のようにします。

@app.get("/users/{id}")
async def user(id):
    return {
      "id": id,
      "userName": "user" + id
    }

パラメータに「3」を指定して、上の API を実行すると、次のような結果となる。 ```bash $ curl http://127.0.0.1:8000/users/3 {"id":"3","userName":"user3"} ```

クエリパラメータを受け取る

@app.get(...) でパスパラメータとして定義されたなかった引数は、自動的にクエリパラメータとして解釈されます。

@app.get("/users")
async def users(id, age):
  return {
    "id": id,
    "age": age
  }

実行結果
$ curl 'http://127.0.0.1:8000/users?id=1&age=20'
{"id":"1","age":"20"}

スポンサーリンク

POST API を作ってみる

GET の次は POST の API を作ってみましょう。

Fast API では、POST のリクエスト・ボディの内容を pydantic を使って定義します。
pydantic とは、Python 用のデータシリアライズ・バリデーションライブラリで、入出力モデルの定義やバリデーションルールによるモデルの検証ができます。

今回は、次の JSON データをリクエスト・ボディに受け取る POST API を作ってみます。

{
  "name": "Yamada",
  "age": 20,
  "mail": "yamada@exsample.com"
}

モデルの定義

まず、リクエストで受信するモデルの定義を行います。

モデルは、pydantic モジュールの BaseModel クラスを継承したクラスで作成します。 今回作成するモデルは、nameage は必須とし、mail は任意入力とします。

from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel

class User(BaseModel):
  name: str
  age: int
  mail: Optional[str] = None

次に、API の宣言をします。

@app.post("/user/")
def create_user(user: User):
  print(user)
  return { "status": "OK"}

POST を試す

まずは、nameagemail の全ての項目に値を設定したデータを POST して正常に動作するか確認してみましょう。

$ curl -X 'POST' \
  'http://127.0.0.1:8000/user/' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "Yamada",
  "age": 20,
  "mail": "yamada@exsample.com"
}'

{"status":"OK"}

次に、mail を省略したデータを送信してみます。

$ curl -X 'POST' \
  'http://127.0.0.1:8000/user/' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "Yamada",
  "age": 20
}'

{"status":"OK"}

mailOptional で任意項目に設定しているため、省略しても問題なく処理されています。

次に、必須入力である age を未設定にしたデータを POST してみます。

$ curl -X 'POST' \
  'http://127.0.0.1:8000/user/' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "Yamada",
  "mail": "yamada@exsample.com"
}'

{"detail":[{"loc":["body","age"],"msg":"field required","type":"value_error.missing"}]}

必須項目を省略すると、上のようなエラーが返ってきます。またエラー時の、HTTP のステータスコードは 422 になります。

VSCodeでデバッグする方法

Fast APIをVSCodeでデバッグする場合は、main.pyに次の行を足します。あとは、VSCodeのデバッグ実行でアプリを起動すれば、ブレークポイント等で止まります。また、reload=True にしているので、実行中にソースコードを変更すると自動で反映されます。

+import uvicorn
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}


+if __name__ == "__main__":
+    uvicorn.run("__main__:app", host="0.0.0.0", port=8000, reload=True, workers=1)

まとめ

Anaconda 環境に FastAPI をインストールする方法と、簡単な API を作成する方法を解説しました。

ほんとに一瞬で API サーバーが構築できるので、フロントエンド開発時のモックサーバーとしても使えそうです。

スポンサーリンク
スポンサーリンク

このブログを検索

Profile

自分の写真
Webアプリエンジニア。 日々新しい技術を追い求めてブログでアウトプットしています。
プロフィール画像は、猫村ゆゆこ様に書いてもらいました。

仕事募集もしていたり、していなかったり。

QooQ