FastAPI for Python を使用してアプリを構築する
公開: 2022-11-29FastAPI は、Python 3.6 以降を使用して最新のアプリケーション プログラミング インターフェイスを構築するための高速で軽量な Web フレームワークです。 このチュートリアルでは、FastAPI を使用してアプリを構築するための基本について説明し、FastAPI が 2021 年の最高のオープンソース フレームワークの 1 つにノミネートされた理由を理解することができます。
独自の FastAPI アプリを開発する準備ができたら、それらをホストする場所を遠くまで探す必要はありません。 Kinsta のアプリケーション ホスティングおよびデータベース ホスティング サービスは、Python に強い Platform as a Service を提供します。
まずは基本を学びましょう。
FastAPI の利点
以下は、FastAPI フレームワークがプロジェクトにもたらす利点の一部です。
- 速度:名前が示すように、FastAPI は非常に高速なフレームワークです。 その速度は、API を構築するための最速のオプションの 1 つと一般に考えられている Go および Node.js の速度に匹敵します。
- 習得とコーディングが簡単: FastAPI は、本番環境で使用できる API を作成するために必要なほぼすべてをすでに把握しています。 FastAPI を使用する開発者は、すべてを最初からコーディングする必要はありません。 数行のコードだけで、RESTful API をデプロイする準備が整います。
- 包括的なドキュメント: FastAPI は OpenAPI ドキュメント標準を使用するため、ドキュメントを動的に生成できます。 このドキュメントでは、FastAPI のエンドポイント、応答、パラメーター、およびリターン コードに関する詳細情報を提供します。
- バグの少ない API: FastAPI はカスタム データ検証をサポートしているため、開発者はバグの少ない API を構築できます。 FastAPI の開発者は、このフレームワークによって人為的なバグが減少し、40% も減少したと自慢しています。
- 型ヒント: types モジュールは Python 3.5 で導入されました。 これにより、変数の
type
を宣言できます。 変数の型が宣言されると、IDE はより適切なサポートを提供し、エラーをより正確に予測できます。
FastAPI の使用を開始する方法
このチュートリアルに従って FastAPI を使い始めるには、最初にいくつかのことを行う必要があります。
Visual Studio Code などのプログラマ用テキスト エディタ/IDE があることを確認します。 その他のオプションには、Sublime Text と Espresso があります。
Python アプリとそのインスタンスを仮想環境で実行することは、一般的な方法です。 仮想環境では、異なるパッケージ セットと構成を同時に実行でき、互換性のないパッケージ バージョンによる競合を回避できます。
仮想環境を作成するには、ターミナルを開いて次のコマンドを実行します。
$ python3 -m venv env
また、仮想環境をアクティブ化する必要があります。 これを行うコマンドは、使用しているオペレーティング システムとシェルによって異なります。 いくつかの環境での CLI アクティベーションの例を次に示します。
# On Unix or MacOS (bash shell): /path/to/venv/bin/activate # On Unix or MacOS (csh shell): /path/to/venv/bin/activate.csh # On Unix or MacOS (fish shell): /path/to/venv/bin/activate.fish # On Windows (command prompt): \path\to\venv\Scripts\activate.bat # On Windows (PowerShell): \path\to\venv\Scripts\Activate.ps1
(一部の Python 対応 IDE は、現在の仮想環境をアクティブにするように構成することもできます。)
次に、FastAPI をインストールします。
$ pip3 install fastapi
FastAPI は API を構築するためのフレームワークですが、API をテストするには、ローカル Web サーバーが必要です。 Uvicorn は、開発に最適な Python 用の非常に高速な Asynchronous Server Gateway Interface (ASGI) Web サーバーです。 Uvicorn をインストールするには、次のコマンドを実行します。
$ pip3 install "uvicorn[standard]"
インストールが成功したら、プロジェクトの作業ディレクトリ内にmain.pyという名前のファイルを作成します。 このファイルは、アプリケーションのエントリ ポイントになります。
簡単な FastAPI の例
サンプル エンドポイントを簡単にセットアップして、FastAPI インストールをテストします。 main.pyファイルに次のコードを貼り付けて、ファイルを保存します。
# main.py from fastapi import FastAPI app = FastAPI() @app.get("/") async def root(): return {"greeting":"Hello world"}
上記のスニペットは、基本的な FastAPI エンドポイントを作成します。 以下は、各行の機能の概要です。
-
from fastapi import FastAPI
: API の機能は、FastAPI Python クラスによって提供されます。 -
app = FastAPI()
: FastAPI インスタンスを作成します。 -
@app.get("/")
: これは、その下の関数がリクエスト処理を担当することを FastAPI に指定する python デコレータです。 -
@app.get("/")
: ルートを指定するデコレーターです。 これにより、サイトのルートにGET
メソッドが作成されます。 結果は、ラップされた関数によって返されます。 - 通信に使用できるその他の操作には、 @app.post(
@app.post()
、@app.put()
、@app.delete()
、@app.options()
、@app.head()
、@app.patch()
などがあります。 、および@app.trace()
。
files ディレクトリで、ターミナルで次のコマンドを実行して API サーバーを起動します。
$ uvicorn main:app --reload
このコマンドで、 main
はモジュールの名前です。 app
オブジェクトはアプリケーションのインスタンスであり、ASGI サーバーにインポートされます。 --reload
フラグは、変更を加えたときにサーバーが自動的にリロードするように指示します。
端末に次のようなものが表示されるはずです。
$ uvicorn main:app --reload INFO: Will watch for changes in these directories: ['D:\\WEB DEV\\Eunit\\Tests\\fast-api'] INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [26888] using WatchFiles INFO: Started server process [14956] INFO: Waiting for application startup. INFO: Application startup complete.
ブラウザーでhttp://localhost:8000
に移動して、API が機能していることを確認します。 「Hello」: 「World」が JSON オブジェクトとしてページに表示されます。 これは、FastAPI を使用して API を作成することがいかに簡単かを示しています。 上記のスニペットの 6 行目にあるように、ルートを定義して Python 辞書を返すだけで済みました。
型ヒントの使用
Python を使用している場合は、 int
、 str
、 float
、 bool
などの基本的なデータ型で変数に注釈を付けることに慣れています。 ただし、Python バージョン 3.9 から、高度なデータ構造が導入されました。 これにより、 dictionaries
、 tuples
、 lists
などのデータ構造を操作できます。 FastAPI の型ヒントを使用すると、pydantic モデルを使用してデータのスキーマを構築し、pydantic モデルを使用してヒントを入力し、提供されているデータ検証を活用できます。
以下の例では、Python での型ヒントの使用が、単純な食事代計算機calculate_meal_fee
で示されています。
def calculate_meal_fee(beef_price: int, meal_price: int) -> int: total_price: int = beef_price + meal_price return total_price print("Calculated meal fee", calculate_meal_fee(75, 19))
型ヒントは、コードの実行方法を変更しないことに注意してください。
FastAPI インタラクティブ API ドキュメント
FastAPI は Swagger UI を使用して、インタラクティブな API ドキュメントを自動的に提供します。 これにアクセスするには、 http://localhost:8000/docs
に移動すると、すべてのエンドポイント、メソッド、およびスキーマを含む画面が表示されます。
この自動的なブラウザー ベースの API ドキュメントは FastAPI によって提供され、それを利用するために他に何もする必要はありません。
これも FastAPI によって提供される代替のブラウザー ベースの API ドキュメントは、Redoc です。 Redoc にアクセスするには、 http://localhost:8000/redoc
に移動します。エンドポイント、メソッド、およびそれぞれの応答のリストが表示されます。
FastAPI でのルートの設定
@app
デコレーターを使用すると、 @app.get
や@app.post
などのルートのメソッドを指定でき、 GET
、 POST
、 PUT
、およびDELETE
と、あまり一般的でないオプションであるHEAD
、 PATCH
、およびTRACE
をサポートします。
FastAPI を使用してアプリを構築する
このチュートリアルでは、FastAPI を使用して CRUD アプリケーションを構築する方法について説明します。 アプリケーションは次のことができます。
- ユーザーを作成する
- ユーザーのデータベース レコードを読み取る
- 既存のユーザーを更新する
- 特定のユーザーを削除する
これらの CRUD 操作を実行するには、API エンドポイントを公開するメソッドを作成します。 その結果、ユーザーのリストを格納できるメモリ内データベースが作成されます。
pydantic ライブラリを使用して、Python 型注釈を使用してデータ検証と設定管理を実行します。 このチュートリアルでは、データの形状を属性を持つクラスとして宣言します。
このチュートリアルでは、インメモリ データベースを使用します。 これは、FastAPI を使用して API を構築する作業をすぐに開始できるようにするためのものです。 ただし、本番環境では、PostgreSQL、MySQL、SQLite、さらには Oracle など、任意のデータベースを利用できます。
アプリの構築
まず、ユーザー モデルを作成します。 ユーザー モデルには次の属性があります。
-
id
: Universal Unique Identifier (UUID) -
first_name
: ユーザーの名 last_name
: ユーザーの姓gender
: ユーザーの性別roles
。これは、admin
者ロールとuser
ロールを含むリストです。
まず、作業ディレクトリにmodels.pyという名前の新しいファイルを作成し、次のコードをmodels.pyに貼り付けてモデルを作成します。
# models.py from typing import List, Optional from uuid import UUID, uuid4 from pydantic import BaseModel from enum import Enum from pydantic import BaseModel class Gender(str, Enum): male = "male" female = "female" class Role(str, Enum): admin = "admin" user = "user" class User(BaseModel): id: Optional[UUID] = uuid4() first_name: str last_name: str gender: Gender roles: List[Role]
上記のコードでは:
-
User
クラスはBaseModel
を拡張し、これはpydantic
からインポートされます。 - 上記のように、ユーザーの属性を定義しました。
次のステップは、データベースを作成することです。 main.pyファイルの内容を次のコードに置き換えます。
# main.py from typing import List from uuid import uuid4 from fastapi import FastAPI from models import Gender, Role, User app = FastAPI() db: List[User] = [ User( id=uuid4(), first_name="John", last_name="Doe", gender=Gender.male, roles=[Role.user], ), User( id=uuid4(), first_name="Jane", last_name="Doe", gender=Gender.female, roles=[Role.user], ), User( id=uuid4(), first_name="James", last_name="Gabriel", gender=Gender.male, roles=[Role.user], ), User( id=uuid4(), first_name="Eunit", last_name="Eunit", gender=Gender.male, roles=[Role.admin, Role.user], ), ]
main.py で:
-
List
のタイプでdb
を初期化し、User
モデルに渡しました - 4 人のユーザーを持つメモリ内データベースを作成しました。各ユーザーは、
first_name
、last_name
、gender
、およびroles
などの必須属性を持ちます。 ユーザーEunit
にはadmin
とuser
の役割が割り当てられ、他の 3 人のユーザーにはuser
の役割のみが割り当てられます。
データベース レコードの読み取り
インメモリ データベースを正常にセットアップし、ユーザーを追加したので、次のステップは、すべてのユーザーのリストを返すエンドポイントをセットアップすることです。 ここで FastAPI の出番です。
main.pyファイルで、 Hello World
エンドポイントのすぐ下に次のコードを貼り付けます。
# main.py @app.get("/api/v1/users") async def get_users(): return db
このコードは、エンドポイント/api/v1/users
を定義し、非同期関数get_users
を作成します。この関数は、データベースdb
のすべての内容を返します。
ファイルを保存すると、ユーザー エンドポイントをテストできます。 ターミナルで次のコマンドを実行して、API サーバーを起動します。
$ uvicorn main:app --reload
ブラウザーで、 http://localhost:8000/api/v1/users
に移動します。 以下に示すように、これにより、すべてのユーザーのリストが返されます。
この段階で、 main.pyファイルは次のようになります。
# main.py from typing import List from uuid import uuid4 from fastapi import FastAPI from models import Gender, Role, User app = FastAPI() db: List[User] = [ User( id=uuid4(), first_name="John", last_name="Doe", gender=Gender.male, roles=[Role.user], ), User( id=uuid4(), first_name="Jane", last_name="Doe", gender=Gender.female, roles=[Role.user], ), User( id=uuid4(), first_name="James", last_name="Gabriel", gender=Gender.male, roles=[Role.user], ), User( id=uuid4(), first_name="Eunit", last_name="Eunit", gender=Gender.male, roles=[Role.admin, Role.user], ), ] @app.get("/") async def root(): return {"Hello": "World",} @app.get("/api/v1/users") async def get_users(): return db
データベース レコードの作成
次のステップは、エンドポイントを作成して、データベースに新しいユーザーを作成することです。 次のスニペットをmain.pyファイルに貼り付けます。
# main.py @app.post("/api/v1/users") async def create_user(user: User): db.append(user) return {"id": user.id}
このスニペットでは、エンドポイントを定義して新しいユーザーを送信し、 @app.post
デコレーターを使用してPOST
メソッドを作成しました。
また、 User
モデルのuser
を受け入れる関数create_user
を作成し、新しく作成したuser
をデータベースdb
に追加 (追加) しました。 最後に、エンドポイントは新しく作成されたユーザーのid
の JSON オブジェクトを返します。
上記のように、エンドポイントをテストするには、FastAPI によって提供される自動 API ドキュメントを使用する必要があります。 これは、Web ブラウザーを使用して投稿要求を行うことができないためです。 http://localhost:8000/docs
に移動して、SwaggerUI が提供するドキュメントを使用してテストします。
データベース レコードの削除
CRUD アプリを構築しているため、アプリケーションには指定されたリソースを削除する機能が必要です。 このチュートリアルでは、エンドポイントを作成してユーザーを削除します。
次のコードをmain.pyファイルに貼り付けます。
# main.py from uuid import UUID from fastapi HTTPException @app.delete("/api/v1/users/{id}") async def delete_user(id: UUID): for user in db: if user.id == id: db.remove(user) return raise HTTPException( status_code=404, detail=f"Delete user failed, id {id} not found." )
そのコードがどのように機能するかの行ごとの内訳は次のとおりです。
-
@app.delete("/api/v1/users/{id}")
:@app.delete()
デコレーターを使用して削除エンドポイントを作成しました。 パスはまだ/api/v1/users/{id}
ですが、ユーザーの ID に対応するパス変数であるid
を取得します。 -
async def delete_user(id: UUID):
: URL からid
を取得するdelete_user
関数を作成します。 -
for user in db:
: これは、データベース内のユーザーをループして、渡されたid
がデータベース内のユーザーと一致するかどうかを確認するようアプリに指示します。 -
db.remove(user)
:id
がユーザーと一致する場合、ユーザーは削除されます。 それ以外の場合、ステータス コード 404 のHTTPException
が発生します。
データベース レコードの更新
ユーザーの詳細を更新するエンドポイントを作成します。 更新できる詳細には、次のパラメーターが含まれます: first_name
、 last_name
、およびroles
。
models.pyファイルで、次のコードをUser
モデルの下、つまりUser(BaseModel):
クラスの後に貼り付けます。
# models.py class UpdateUser(BaseModel): first_name: Optional[str] last_name: Optional[str] roles: Optional[List[Role]]
このスニペットでは、クラスUpdateUser
がBaseModel
を拡張します。 次に、 first_name
、 last_name
、 roles
などの更新可能なユーザー パラメータをオプションに設定します。
次に、エンドポイントを作成して、特定のユーザーの詳細を更新します。 main.pyファイルで、 @app.delete
デコレーターの後に次のコードを貼り付けます。
# main.py @app.put("/api/v1/users/{id}") async def update_user(user_update: UpdateUser, id: UUID): for user in db: if user.id == id: if user_update.first_name is not None: user.first_name = user_update.first_name if user_update.last_name is not None: user.last_name = user_update.last_name if user_update.roles is not None: user.roles = user_update.roles return user.id raise HTTPException(status_code=404, detail=f"Could not find user with id: {id}")
上記のコードでは、次のことを行いました。
- 更新エンドポイント
@app.put("/api/v1/users/{id}")
を作成しました。 これには、ユーザーの ID に対応する変数パラメーターid
があります。 -
UpdateUser
クラスとid
をupdate_user
というメソッドを作成しました。 -
for
ループを使用して、渡されたid
に関連付けられたユーザーがデータベースに存在するかどうかを確認しました。 - ユーザーのパラメーターのいずれかが
is not None
(null でない) かどうかを確認しました。first_name
、last_name
、roles
などのパラメーターが null でない場合は、更新されます。 - 操作が成功すると、ユーザー ID が返されます。
- ユーザーが見つからなかった場合は、ステータス コード 404 の
HTTPException
例外と、Could not find user with id: {id}
というメッセージが発生します。
このエンドポイントをテストするには、Uvicorn サーバーが実行されていることを確認してください。 実行されていない場合は、次のコマンドを入力します。
uvicorn main:app --reload
以下は、テストのスクリーンショットです。
概要
このチュートリアルでは、Python 用の FastAPI フレームワークについて学び、FastAPI を利用したアプリケーションをいかに迅速に起動して実行できるかを自分の目で確かめました。 フレームワークを使用して CRUD API エンドポイントを構築する方法 (データベース レコードの作成、読み取り、更新、および削除) を学習しました。
ウェブアプリ開発を次のレベルに引き上げたい場合は、Kinsta のアプリケーション ホスティングとデータベース ホスティングのプラットフォームを確認してください。 FastAPI と同様、非常にシンプルです。