【FastAPI】基礎講座① installとサンプルコードの実行

1. FastAPIの紹介と基本概念の説明

FastAPIは、高速で効率的なWeb APIを構築するためのモダンなPythonフレームワークです。FastAPIは、高速な処理速度とスケーラビリティ、簡潔で直感的な構文、自動的なAPIドキュメント生成など、多くの優れた特徴を提供しています。

【FastAPIの特徴と利点】

高速なパフォーマンス: FastAPIは、高速な処理速度を提供するために、高性能なPythonフレームワークであるStarletteをベースにしています。非同期処理をサポートすることで、高いパフォーマンスとスケーラビリティを実現しています。

簡潔な記述と型ヒント: FastAPIは、Pythonの型ヒントを活用して、リクエストとレスポンスのデータ構造を定義することができます。これにより、自動的な入力検証と出力シリアライズが行われ、コードの品質と保守性が向上します。

自動的なAPIドキュメント生成: FastAPIは、OpenAPIおよびSwagger仕様に基づいた自動的なAPIドキュメント生成をサポートしています。APIのエンドポイント、リクエストとレスポンスのデータモデル、パラメータ、認証などの情報が自動的にドキュメント化され、開発者が簡単にAPIの利用方法を理解できます。

フレームワークの柔軟性: FastAPIは、データベースの統合、認証、テスト、ログなど、さまざまな機能を柔軟にカスタマイズするための豊富な拡張性を提供しています。他のPythonパッケージやツールとの統合も容易であり、開発者のニーズに合わせた柔軟な開発が可能です。

 RESTful APIの基本概念の説明

【RESTful APIの基本概念】

REST(Representational State Transfer)は、Webアプリケーションの設計原則の1つであり、リソース指向アーキテクチャとして知られています。RESTful APIは、この設計原則に基づいて作成されたWeb APIのことを指します。

リソース: RESTful APIでは、リソースと呼ばれる情報の単位が中心となります。例えば、ユーザー、商品、記事などはそれぞれ独自のリソースとして表現されます。

URI(Uniform Resource Identifier): リソースは一意の識別子であるURIを持ちます。URIは、リソースを一意に特定するためのアドレスのようなものであり、APIエンドポイントを表します。

HTTPメソッド: RESTful APIでは、HTTPメソッドを使用してリソースに対する操作を表現します。代表的なHTTPメソッドとしてはGET(リソースの取得)、POST(リソースの作成)、PUT(リソースの更新)、DELETE(リソースの削除)などがあります。

ステートレス性: RESTful APIはステートレスな設計を採用しています。つまり、クライアントとサーバー間の通信は相互に依存しないため、リクエストごとに必要な情報を提供する必要があります。セッション状態を保持する必要がないため、スケーラビリティが向上します。

レスポンスの形式: RESTful APIは、一般的にJSONやXMLなどのデータ形式を使用してレスポンスを返します。クライアントは受け取ったデータを解析し、必要な情報を抽出して利用します。

RESTful APIは、リソース指向の設計原則に基づいてシンプルで柔軟なアプリケーションインターフェースを提供します。FastAPIは、このRESTfulアーキテクチャに完全に準拠し、簡潔な構文と高速なパフォーマンスを組み合わせることで、効率的なAPI開発を実現します。

2. 環境のセットアップとプロジェクトの作成

【環境のセットアップとプロジェクトの作成】

FastAPIを使用するためには、PythonのインストールとFastAPIのインストールが必要です。また、プロジェクトを適切に管理するためにディレクトリ構造を作成することも重要です。

【Pythonのインストール】

Pythonの公式ウェブサイト(https://www.python.org)から、最新バージョンのPythonをダウンロードします。

ダウンロードしたインストーラを実行し、Pythonをインストールします。インストールプロセスでは、Pythonのバージョンを選択し、必要なパス設定を行います。

(Pythonはインストールされているものとして詳細の説明は省きます)

インストールが完了したら、コマンドプロンプト(Windows)またはターミナル(Mac/Linux)を開き、python –versionコマンドを実行してインストールされたPythonのバージョンを確認します。

【FastAPIのインストール】

https://github.com/tiangolo/fastapi

コマンドプロンプト(Windows)またはターミナル(Mac/Linux)を開き、以下のコマンドを実行してFastAPIをインストールします。

pip install fastapi

venv環境の場合はパスを通します

export PATH="/env/bin:$PATH" 

source ~/.zshrc

インストールが完了したら、以下のコマンドを実行してFastAPIが正しくインストールされたか確認します。

uvicornも必要になるのでインストールします。

pip install "uvicorn[standard]"
Hint:このコマンドの意味は?
Uvicornと呼ばれるASGI(Asynchronous Server Gateway Interface)サーバーをインストールします。Uvicornは、非同期処理をサポートする高速なWebサーバーであり、FastAPIアプリケーションの実行に使用されます。[standard]: オプションとして指定された部分で、Uvicornと共に標準的な依存関係を含むパッケージをインストールする指示です。これにより、Uvicornの実行に必要な依存関係が同時にインストールされます。このコマンドを実行することで、Uvicornとその依存関係が自動的にインストールされ、FastAPIアプリケーションを実行するための環境が整います。UvicornはFastAPIに統合されており、FastAPIアプリケーションの開発やデバッグ時に利用されます。

なお、[standard]の代わりに、追加のオプションやパッケージ名を指定することで、さまざまなモジュールや拡張機能を含めたカスタムなインストールも可能です。

ASGIサーバーとは?

ASGI(Asynchronous Server Gateway Interface)サーバーは、非同期通信をサポートするWebサーバーです。ASGIはPythonのWebアプリケーションフレームワーク(例: FastAPI)とWebサーバー(例: Uvicorn)の間の標準化されたインターフェースです。

従来のWebサーバーは、同期的なリクエスト-レスポンスモデルを使用していました。つまり、1つのリクエストが処理されるまで次のリクエストは待たされます。これは効率的でないため、高負荷やリアルタイムな要件のあるアプリケーションには適していません。

ASGIサーバーは、非同期処理によってリクエストを並行して処理できるため、高速で効率的なWebアプリケーションの開発が可能です。ASGIサーバーはPythonの非同期フレームワークと組み合わせて使用され、同時に多数のリクエストを処理できます。

ASGIは、ウェブサーバー(例: Uvicorn、Daphne)とウェブアプリケーションフレームワーク(例: FastAPI、Starlette、Django Channels)の間の共通のインターフェースを提供し、効率的な非同期通信を可能にします。

FastAPIのようなASGIフレームワークとUvicornのようなASGIサーバーを組み合わせることで、高速でスケーラブルなWebアプリケーションを構築することができます。

Uvicornがなぜ必要なのか?

一般的なWebサーバーソフトウェア(Apache、Nginx、IIS、Lighttpd、Caddy)は、従来の同期的なWebサーバーとしての役割を果たします。これらのサーバーは、HTTPリクエストを受け取り、同期的に処理し、レスポンスを返すという基本的な機能を提供します。主な用途は静的なコンテンツの配信や動的なコンテンツの処理、リバースプロキシ、負荷分散などです。

一方、UvicornはASGI(Asynchronous Server Gateway Interface)サーバーです。ASGIは非同期なWebサーバーとアプリケーションの間のインターフェース規格であり、非同期なリクエスト処理や高性能な並列処理を可能にします。UvicornはASGIアプリケーション(例:FastAPI)を実行するためのサーバーとして機能し、非同期なリクエスト処理や高いスループットの要件に適しています。

以下はUvicornと従来のWebサーバーソフトウェアの主な違いです:

同期 vs 非同期: 従来のWebサーバーは同期的な処理を行いますが、Uvicornは非同期な処理をサポートします。非同期な処理はI/O待機時間を最小限に抑え、同時に複数のリクエストを効率的に処理することができます。

パフォーマンス: Uvicornは非同期I/O処理と並列処理を活用し、高いスループットと効率的なリクエスト処理を提供します。一方、従来のWebサーバーは同期的な処理であり、リクエストの待機やブロッキングが発生する可能性があります。

プロトコル: 従来のWebサーバーは通常、HTTPプロトコルを使用します。一方、UvicornはASGIプロトコルを使用し、非同期なリクエスト処理を実現します。

ホットリロード: Uvicornはホットリロード機能を提供し、ソースコードの変更を検知して自動的にアプリケーションを再起動できます。一部の従来のWebサーバーもホットリロード機能をサポートしていますが、全てのサーバーがこの機能を提供するわけではありません。

【プロジェクトのディレクトリ構造の作成】

プロジェクト用のディレクトリを作成します。任意の名前を選び、そのディレクトリに移動します。

プロジェクトのディレクトリ内に以下のような基本的なディレクトリ構造を作成します。

project/

├── main.py

main.py: FastAPIアプリケーションのメインファイルです。ここにAPIエンドポイントやルーティングの定義を記述します。

続いてmain.pyに下記を記述します。

port Union

from fastapi import FastAPI




app = FastAPI()




@app.get("/")

def read_root():

    return {"Hello": "World"}

下記で実行できます。

$ uvicorn main:app --reload

http://127.0.0.1:8000

ローカルサーバーでHell Worldと表示されれば成功です

リクエストとレスポンスの処理

FastAPIでは、リクエストパラメータの取得やパスパラメータ、クエリパラメータ、リクエストボディの処理が簡単に行えます。また、レスポンスの生成と返却もシンプルな方法で実現できます。

リクエストパラメータの取得方法

リクエストパラメータは、URLに含まれるパスパラメータやクエリパラメータとして渡されます。FastAPIでは、パスパラメータは{}で囲んだ形式で指定し、関数の引数として受け取ることができます。クエリパラメータは、関数の引数にデフォルト値を指定することで取得できます。

パスパラメータは、URLの一部に含まれる動的な値を表すために使用されるパラメータです。URLパス内に特定のパラメータを埋め込むことで、その値に基づいて異なるリソースやエンドポイントにアクセスすることができます。

パスパラメータは、URL内の特定の部分を中括弧 {} で囲んで指定します。中括弧内にパラメータ名を記述し、その部分が動的な値として解釈されます。例えば、以下のようなURLがあるとします。

/items/{item_id}

ここで、item_idはパスパラメータとなります。実際のリクエスト時には、item_idの部分に具体的な値を指定することで、対応するリソースやエンドポイントにアクセスします。例えば、以下のようなURLが該当します。

/items/1

/items/2

/items/3

上記の例では、/items/の後ろに異なるitem_idが指定されています。パスパラメータを利用することで、URL内の値を動的に取得し、その値に基づいた処理を行うことができます。

FastAPIでは、パスパラメータを関数の引数として受け取ることができます。例えば、以下のようなコードでパスパラメータを取得することができます。

from fastapi import FastAPI




app = FastAPI()




@app.get("/items/{item_id}")

async def read_item(item_id: int):

    return {"item_id": item_id}

上記の例では、read_item関数が/items/{item_id}に対応するエンドポイントとなっており、item_idが関数の引数として渡されます。この関数内でitem_idの値を利用することができます。

パスパラメータを使用することで、URL内の動的な値を取得して処理することができます。これにより、異なるリソースやエンドポイントへのアクセスを効率的に行うことができます。

app2 = FastAPI()




@app2.get("/items/{item_id}")

async def read_item(item_id: int, q: str = None):

    return {"item_id": item_id, "q": q}

ターミナル

uvicorn main:app2 --reload

上記の例では、item_idがパスパラメータとして取得され、qはクエリパラメータとして取得されます。

http://127.0.0.1:8000/items/1にアクセスし、{“item_id”:1,”q”:null}が表示されれば成功です。

リクエストボディの処理方法

リクエストボディのデータは、POSTPUTメソッドなどで送信されます。FastAPIでは、リクエストボディのデータをモデルクラスで定義し、関数の引数として受け取ることができます。

from fastapi import FastAPI

from pydantic import BaseModel


app = FastAPI()

class Item(BaseModel):

    name: str

    price: float

@app.post("/items/")

async def create_item(item: Item):

    return {"item": item}

上記の例では、Itemクラスがリクエストボディのスキーマを定義しています。関数の引数としてitemを指定することで、リクエストボディのデータが自動的にItemクラスのインスタンスとして受け取られます。

リクエストの方法

上記のコードでは、/items/エンドポイントに対してPOSTリクエストを送信することで、create_item関数が実行されます。リクエストボディにはnameとpriceのフィールドを持つJSONデータを含める必要があります。

以下は、Pythonのrequestsライブラリを使用してPOSTリクエストを送信する例です。

(client.py)
import requests


url = "http://localhost:8000/items/"

data = {

    "name": "Example Item",

    "price": 9.99
}


response = requests.post(url, json=data)

print(response.json())

上記のコードでは、urlにFastAPIアプリケーションが実行されているサーバーのURLを指定します。dataにはリクエストボディに含めるデータを指定します。requests.post()メソッドを使用してPOSTリクエストを送信し、json=dataを指定することでデータをJSON形式で送信します。

サーバーからのレスポンスはresponse.json()で取得し、表示します。この例では、サーバーからのレスポンスとして受け取ったJSONデータが表示されます。

この方法で、FastAPIアプリケーションに対してPOSTリクエストを送信することができます。応じたレスポンスを受け取ることができます。ただし、FastAPIアプリケーションを実行しているサーバーのURLやポート番号などは、実際の環境に合わせて適切に指定する必要があります。

ターミナルで下記を実行

uvicorn main:app3 --reload

別のターミナルで下記を実行

 python3 client.py 

{‘item’: {‘name’: ‘Example Item’, ‘price’: 9.99}}

Hint:リクエストパラメータとリクエストボディの違い
リクエストパラメータとリクエストボディは異なるものです。
リクエストパラメータは、URLの一部に含まれる情報であり、主にGETメソッドによって送信されます。例えば、以下のようなURLを考えてみましょう。
/items/{item_id}
ここで、item_idはパスパラメータとして扱われるリクエストパラメータです。リクエストパラメータはURL内に埋め込まれており、特定のリソースやエンドポイントにアクセスするための識別子や条件などを表現します。リクエストパラメータはURL内に直接記述されるため、リクエストボディとは異なり、リクエストヘッダーには含まれません。
一方、リクエストボディは、主にPOSTやPUTメソッドなどで送信されるリクエストの一部です。リクエストボディは、リクエストの目的や要求に応じたデータを含むため、主にクライアントがサーバーにデータを送信する際に使用されます。リクエストボディはリクエストの一部として送信されるため、リクエストヘッダーには適切なContent-Typeが指定されており、データの形式(JSON、XML、フォームデータなど)とサイズが示されます。
FastAPIでは、リクエストパラメータとリクエストボディを別々の方法で処理します。リクエストパラメータはパスパラメータやクエリパラメータとして取得され、関数の引数として受け取ることができます。一方、リクエストボディはモデルクラスを使用して定義し、関数の引数として受け取ることができます。
要するに、リクエストパラメータはURLに含まれる識別子や条件を表し、リクエストボディはリクエストに含まれるデータ本体を表します。
Hint:pydanticとは?
pydanticがあることで、リクエストボディのバリデーションが可能です。
具体的には、Itemクラスでpriceフィールドを必須として定義していますが、リクエストボディにそのフィールドが含まれていない場合には、バリデーションエラーが発生します。これにより、必要なデータが欠落している場合にはエラーレスポンスが返されます。
Pydanticを使用することで、データのバリデーションを簡単に行うことができます。データモデルにバリデーションルールを追加することで、不正なデータが提供された場合にはエラーを返すことができます。これにより、データの整合性を保ちつつ、信頼性の高いAPIを開発することができます。

レスポンスの生成と返却方法

FastAPIでは、レスポンスをJSON形式で生成し、return文で返却することができます。関数の返り値は辞書やモデルクラスのインスタンスとなり、自動的にJSON形式に変換されます。

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")

async def read_item(item_id: int):

    return {"item_id": item_id, "name": "Example Item"}

上記の例では、read_item関数がGETメソッドのエンドポイント/items/{item_id}に対応しています。関数内で生成した辞書がJSON形式に変換されてレスポンスとして返却されます。

FastAPIでは、レスポンスのステータスコードやヘッダーをカスタマイズすることも可能です。例えば、以下のようにステータスコードやヘッダーを指定することができます。

from fastapi import FastAPI, HTTPException




app = FastAPI()




@app.get("/items/{item_id}")

async def read_item(item_id: int):

    if item_id < 1:

        raise HTTPException(status_code=400, detail="Item ID must be greater than 0")

    return {"item_id": item_id, "name": "Example Item"}

上記の例では、item_idが1未満の場合にはステータスコード400とエラーメッセージが含まれたレスポンスが返却されます。

FastAPIでは他にも多くのレスポンス処理のオプションがあり、レスポンスモデルの定義やフォーマット指定などもサポートされています。

以上が、「リクエストとレスポンスの処理」についての概要です。FastAPIを使って柔軟で効率的なリクエストとレスポンスの処理を実現することができます。

 

Hint:GETとPOSTの違い

5. データベースの統合

FastAPIでは、さまざまなデータベースとの統合がサポートされています。データベースはアプリケーションで使用されるデータの永続化や取得に重要な役割を果たします。ここでは、主にFAISSとRedisの統合に焦点を当てて解説します。

FAISS(Facebook AI Similarity Search)

FAISSは、高速な類似性検索を実現するためのライブラリです。特にベクトルデータの類似性検索に効果的であり、機械学習や自然言語処理の分野で広く使用されています。FastAPIとの統合により、FAISSを使用して高速な検索機能を実現することができます。

Redis

Redisは高速なキーバリューストアであり、メモリ内データ構造サーバーとして広く使用されています。FastAPIとRedisの統合により、データのキャッシュやセッション管理など、さまざまな用途でRedisを活用することができます。

長くなってしまったので続きは次の記事で

コメント

タイトルとURLをコピーしました