ASGIを探る:PythonのAsync Protocol for Web Apps
Wenhao Wang
Dev Intern · Leapcell

FastAPI開発におけるASGIとUvicornの理解
FastAPIで開発する際、Uvicornサーバーを使用する必要があります。初心者はなぜだろうと思うかもしれません。今日は、この質問にお答えします。
Uvicorn
HTTPを使用して簡単なHTTPリクエストを実装してみましょう。
import json # ヘッダー内のバイトを文字列に変換するヘルパー関数を定義する def convert_bytes_to_str(data): if isinstance(data, bytes): return data.decode('utf-8') if isinstance(data, tuple): return tuple(convert_bytes_to_str(item) for item in data) if isinstance(data, list): return [convert_bytes_to_str(item) for item in data] if isinstance(data, dict): return {key: convert_bytes_to_str(value) for key, value in data.items()} return data async def app(scope, receive, send): # print(scope) data = convert_bytes_to_str(scope) print(json.dumps(data, indent=4)) # リクエストのタイプを確認する if scope['type'] == 'http': # HTTPリクエストボディを待つ event = await receive() # レスポンスコンテンツ response_body = json.dumps({"message": "Hello, ASGI!"}).encode('utf-8') # HTTPレスポンスヘッダーを送信する await send({ 'type': 'http.response.start', 'status': 200, 'headers': [ (b'content-type', b'application/json'), ], }) # HTTPレスポンスボディを送信する await send({ 'type': 'http.response.body', 'body': response_body, })
scope
フィールドにはバイナリ文字列が含まれているため、変換関数convert_bytes_to_str
が必要です。簡単に分析してみましょう。リクエストパスとメソッドに関連する情報はscope
にあります。scope
はHTTPだけでなく、それ以上のものをサポートしているので、現在のプロトコルのタイプを判断するためにtype
を使用する必要があります。次に、receive
関数を使用してリクエストボディを受信します。次に、json.dumps
を使用してレスポンスボディを作成し、encode
でエンコードします。最後に、リクエストヘッダーとリクエストボディを送信します。
ここでは、データを2回送信します。この設計は、非同期プログラミングの要件を満たし、さまざまなアプリケーションシナリオ(ストリーミングレスポンス)の処理能力を強化します。実際のプロジェクトを理解することで、ASGIを理論的な基盤から理解できるようになりました。
ASGI
Asynchronous Server Gateway Interface(ASGI)は、非同期Webアプリケーションを構築するためのPythonプロトコルです。
ASGIの主な機能
- 非同期サポート: 非同期プログラミングを有効にします。
- マルチプロトコルサポート: WebSocketやロングポーリングなどのプロトコルをサポートします。つまり、http/https/websocketをサポートします。
- 同時実行サポート: 複数のリクエストを同時に処理できます。
- 通信: アプリケーションとサーバー、およびアプリケーションの異なる部分は、メッセージを送受信することでやり取りします。
ASGIプロトコルの構成
- アプリケーションインターフェース
- ASGIアプリケーションインターフェースは、アプリケーションがASGIサーバーとどのようにやり取りするかを定義します。ASGIアプリケーションは、呼び出し可能なオブジェクトであり、通常は2つのパラメータ(
scope
とreceive
)を受け入れ、send
という非同期ジェネレータを返します。- scope: リクエストに関する情報を含む辞書。リクエストタイプ(HTTPまたはWebSocket)、パス、クエリ文字列、サーバー情報などが含まれます。
- receive: ASGIサーバーからイベントを受信するために使用される非同期呼び出しです。
- send: イベントをASGIサーバーに送り返すために使用される非同期ジェネレータです。
- ASGIアプリケーションインターフェースは、アプリケーションがASGIサーバーとどのようにやり取りするかを定義します。ASGIアプリケーションは、呼び出し可能なオブジェクトであり、通常は2つのパラメータ(
- サーバーインターフェース
- サーバーインターフェースの主な責任は次のとおりです。
- クライアントからの接続を受け入れる。
- 各接続の
scope
を作成する。 - アプリケーションの
receive
およびsend
メソッドを呼び出して、イベントを渡す。 - ネットワーク例外を処理し、接続を閉じる。
- サーバーインターフェースの主な責任は次のとおりです。
- イベントループインターフェース
- イベントループインターフェースは、ASGIプロトコルの暗黙的な部分です。ASGIプロトコルによって直接定義されるのではなく、ASGIサーバーによって管理されます。
- イベントループは、非同期タスクのスケジュールと実行を担当し、非同期プログラミングの中核となります。その主な機能は次のとおりです。
- 非同期タスクの実行とスケジュール。
- ネットワークリクエストなどの非同期I/O操作の管理。
- コールバック関数と非同期ジェネレータの処理。
- ASGIでは、イベントループは通常、次のPythonライブラリによって提供されます。
- asyncio: Python標準ライブラリの非同期I/Oフレームワーク。
- uvloop:
libuv
に基づく非同期イベントループで、Uvicornサーバーでよく使用されます。
ASGIサーバーとアプリケーションは、イベントループに依存して非同期操作を実行し、多数の同時接続を効率的に処理できるようにします。
ASGIイベント
ASGIイベント駆動モデルは、ライフサイクル管理(起動とシャットダウン)、HTTPリクエスト処理、およびWebSocket接続管理を処理します。さまざまなタイプのイベントを通じて、開発者は接続とデータフローを正確に制御して、非同期および同時処理を実現できます。
- ライフスパンイベント
- ライフスパンイベントは、ASGIアプリケーションの起動およびシャットダウンサイクルに関連しています。これらは通常、初期化およびクリーンアップタスクを実行するために使用されます。
- lifespan.startup
- lifespan.shutdown
- ライフスパンイベントは、ASGIアプリケーションの起動およびシャットダウンサイクルに関連しています。これらは通常、初期化およびクリーンアップタスクを実行するために使用されます。
- HTTPイベント
- ASGIのHTTPリクエストの処理は、複数のイベントに分割されており、各HTTPリクエストの詳細を管理できます。
- http.request
- http.response.start
- http.response.body
- http.disconnect
- websocket.send
- ASGIのHTTPリクエストの処理は、複数のイベントに分割されており、各HTTPリクエストの詳細を管理できます。
- WebSocketイベント
- ASGIはWebSocket接続をサポートし、双方向通信を可能にします。
- websocket.connect
- websocket.receive
- ASGIはWebSocket接続をサポートし、双方向通信を可能にします。
ASGIライフサイクル
ASGIアプリケーションのライフサイクルは、アプリケーションが起動およびシャットダウン中に通過する段階を指します。これは、ライフスパンイベントチャネルによって管理されます。
scope['type']: lifespan
message['type']
: 起動およびシャットダウンのメッセージ:lifespan.startup/lifespan.shutdown
- 送信タイプ:
{'type': 'lifespan.shutdown.complete'}
ASGIのライフサイクルは、アプリケーションの起動とシャットダウン、およびリクエストの確立、処理、応答、およびシャットダウンの2つの部分に分かれています。
Uvicornとアプリケーション層
前述のように、UvicornはASGIサーバー層を実装しています。ただし、アプリケーション層では、低レベルすぎるため、あまりユーザーフレンドリーではありません。したがって、多くの高レベルフレームワークが登場しました。
- Starlette: 高パフォーマンスのWebサービスを構築するための軽量ASGIフレームワーク/ツールキット。FastAPIの基本的なコンポーネントであり、単純なWebアプリケーションを作成するために単独で使用することもできます。
- FastAPI: 最新の高速(高パフォーマンス)APIを構築するためのWebフレームワークで、Python 3.6+の型ヒントで使用されます。Starletteと標準のPython型ヒントに基づいており、自動データ検証とシリアル化、およびインタラクティブなAPIドキュメントの生成を提供します。
ここでは他の側面について詳しく説明する必要はありません。情報が多すぎると圧倒される可能性があります。Uvicornはapp
を必要とするため、これら2つのフレームワークでは、インスタンス化されたオブジェクトがapp
になります。次に、Uvicorn CLIを使用してアプリケーションを起動します。
uvicorn main:app --reload
まとめ
この記事では、主にUvicornを通じてPython Web ASGIプロトコルについて説明します。ASGIは、Pythonの非同期サーバーゲートウェイインターフェースであり、最新のPython Webプログラムの非同期、同時実行、およびマルチプロトコル機能を統合します。
Leapcell: Python Webホスティング、非同期タスク、およびRedisに最適なサーバーレスプラットフォーム
最後に、Pythonプロジェクトのデプロイに最適なプラットフォームをお勧めします:Leapcell
1. 多言語サポート
- JavaScript、Python、Go、またはRustで開発します。
2. 無制限のプロジェクトを無料でデプロイ
- 使用量に応じてのみ支払います—リクエスト、料金はかかりません。
3. 比類のないコスト効率
- アイドル料金なしの従量課金制。
- 例:25ドルで、平均応答時間60msで694万リクエストをサポートします。
4. 合理化された開発者エクスペリエンス
- 簡単なセットアップのための直感的なUI。
- 完全に自動化されたCI/CDパイプラインとGitOps統合。
- 実用的な洞察を得るためのリアルタイムメトリックとロギング。
5. 簡単なスケーラビリティと高性能
- 高い同時実行を簡単に処理するための自動スケーリング。
- 運用上のオーバーヘッドはゼロ—構築に集中するだけです。
Leapcell Twitter: https://x.com/LeapcellHQ