1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Python Webの未来: ASGIと非同期処理

Posted at

Group39.png

Leapcell: Python Webホスティング、非同期タスク、およびRedisのための最高のサーバレスプラットフォーム

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つのパラメータ scopereceive を受け取り、send 非同期ジェネレータを返します。
      • scope:リクエストに関する情報、例えばリクエストタイプ(HTTPまたはWebSocket)、パス、クエリ文字列、サーバ情報などを含む辞書です。
      • receive:ASGIサーバからイベントを受け取るために使用される非同期呼び出しです。
      • send:ASGIサーバにイベントを返すために使用される非同期ジェネレータです。
  • サーバインターフェイス
    • サーバインターフェイスの主な責務は以下の通りです:
      • クライアントからの接続を受け付ける。
      • 各接続に対して scope を作成する。
      • アプリケーションの receivesend メソッドを呼び出してイベントを渡す。
      • ネットワーク例外を処理し、接続を閉じる。
  • イベントループインターフェイス
    • イベントループインターフェイスはASGIプロトコルの暗黙的な部分です。ASGIサーバによって管理され、ASGIプロトコルによって直接定義されるものではありません。
    • イベントループは非同期タスクのスケジューリングと実行を担当し、これが非同期プログラミングの核心です。その主な機能は以下の通りです:
      • 非同期タスクの実行とスケジューリング。
      • ネットワークリクエストなどの非同期I/O操作の管理。
      • コールバック関数と非同期ジェネレータの処理。
    • ASGIでは、イベントループは通常以下のPythonライブラリによって提供されます:
      • asyncio:Python標準ライブラリ内の非同期I/Oフレームワーク。
      • uvlooplibuvに基づく非同期イベントループで、Uvicornサーバとともによく使用されます。

ASGIサーバとアプリケーションは、イベントループに依存して非同期操作を実行し、多数の同時接続を効率的に処理できるようになります。

ASGIイベント

ASGIのイベント駆動型モデルは、ライフサイクル管理(起動とシャットダウン)、HTTPリクエストの処理、WebSocket接続管理を行います。異なる種類のイベントを通じて、開発者は接続とデータフローを正確に制御し、非同期および並列処理を実現できます。

  • ライフサイクルイベント
    • ライフサイクルイベントは、ASGIアプリケーションの起動とシャットダウンサイクルに関連付けられています。通常、初期化とクリーンアップタスクを実行するために使用されます。
      • lifespan.startup
      • lifespan.shutdown
  • HTTPイベント
    • ASGIによるHTTPリクエストの処理は、複数のイベントに分割され、各HTTPリクエストの詳細を管理できます。
      • http.request
      • http.response.start
      • http.response.body
      • http.disconnect
      • websocket.send
  • WebSocketイベント
    • ASGIはWebSocket接続をサポートし、双方向通信を可能にします。
      • websocket.connect
      • websocket.receive

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のための最高のサーバレスプラットフォーム

barndpic.png

最後に、Pythonプロジェクトのデプロイに最適なプラットフォームをおすすめします:Leapcell

1. マルチ言語サポート

  • JavaScript、Python、Go、またはRustで開発できます。

2. 無料で無制限のプロジェクトをデプロイ

  • 使用量に応じてのみ課金 — リクエストがなければ料金は発生しません。

3. 圧倒的なコスト効率

  • 使い放題で、アイドル時の料金はかかりません。
  • 例:25ドルで平均応答時間60msで694万回のリクエストをサポート。

4. シンプルな開発者体験

  • 直感的なUIで簡単にセットアップできます。
  • 完全自動化されたCI/CDパイプラインとGitOps統合。
  • アクション可能な洞察のためのリアルタイムメトリクスとログ。

5. 簡単なスケーラビリティと高性能

  • 高い同時接続数を簡単に処理できる自動スケーリング。
  • オペレーションオーバーヘッドはゼロ — 構築に集中できます。

Frame3-withpadding2x.png

ドキュメントで詳細を確認!

Leapcell Twitter:https://x.com/LeapcellHQ

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?