Open2

【Python/FastAPI/uvicorn】ASGIとWSGIについて📝

まさぴょん🐱まさぴょん🐱

ASGI (Asynchronous Server Gateway Interface) とは?

ASGI は Python Web アプリケーションの “実行インターフェース” を非同期対応に拡張した仕様 です。
WSGI が同期的な HTTP リクエスト/レスポンスに特化していたのに対し、ASGI は HTTP・WebSocket・長時間接続 など多様なプロトコルを 同じアプリケーション定義 で扱えるよう設計されています。


誕生の背景

背景 詳細
WSGI の限界 1 リクエスト=1 スレッド/プロセス前提。
WebSocket や Server-Sent Events など “継続接続” に非対応。
Python 3.5 の async/await 非同期 IO が標準化 → イベントループ駆動で多数同時接続を効率処理できる土壌が整う。
リアルタイム Web の普及 チャット、ゲーム、IoT、AI ストリーミングなど双方向通信・低レイテンシが必須に。

コアアイデア

要素 説明
アプリケーション callable python async def app(scope, receive, send): …
3 つの引数を取り、非同期関数であることが必須。
scope 接続単位のメタデータ(プロトコル種別、パス、ヘッダなど)。
receive / send インターフェースは 「メッセージの受信・送信」。HTTP や WebSocket も「メッセージ列」で統一的に表現する。

メッセージタイプ(v3.0 仕様)

  • http.request / http.response.*
  • websocket.connect / websocket.receive / websocket.send / websocket.disconnect
  • lifespan.startup / lifespan.shutdown

WSGI との違い(クイック比較)

観点 WSGI ASGI
実装関数 def app(environ, start_response) async def app(scope, receive, send)
対応プロトコル HTTP のみ HTTP / WebSocket / SSE / 任意のカスタム
同期 / 非同期 同期 (スレッド or プロセス並列) 非同期 I/O (イベントループ)/同期も併用可
長時間接続 不可 可能(双方向リアルタイム通信)
代表実装 Gunicorn + 例:Flask, Django (同期) Uvicorn / Hypercorn / Daphne + FastAPI, Starlette, Django Channels など

典型的なスタック図

┌─────────────┐
│   ASGI App  │ 例: FastAPI / Starlette
└─────┬───────┘
      │ ASGI 3.0 コールプロトコル
┌─────▼───────┐
│  ASGI Server │ 例: Uvicorn / Hypercorn / Daphne
└─────┬───────┘
      │ ソケット通信 (asyncio / uvloop / trio)
┌─────▼───────┐
│   OS Kernel  │ TCP, QUIC, etc.
└─────────────┘

ミニマル例(HTTP エコー)

# example.py
async def app(scope, receive, send):
    assert scope["type"] == "http"

    # リクエストボディを読む
    body = b""
    while True:
        event = await receive()
        body += event.get("body", b"")
        if not event.get("more_body"):
            break

    await send({
        "type": "http.response.start",
        "status": 200,
        "headers": [[b"content-type", b"text/plain"]]
    })
    await send({
        "type": "http.response.body",
        "body": body or b"Hello, ASGI!"
    })
# 起動
uvicorn example:app --port 8000

使いどころ & メリット

  • リアルタイム API: チャット、通知、ゲーム、株価・為替配信
  • ストリーミング AI: 音声認識/生成、LLM ストリーム応答
  • IoT ゲートウェイ: 多数センサーを非同期で捌く
  • WSGI 資産も 同期ブロッカーとしてスレッドプールで共存 可能

まとめ

ASGI は 「Python Web の次世代標準」 として、HTTP だけでなく WebSocket など双方向通信まで 単一の抽象レイヤー で統一。
従来の WSGI アプリより スケーラブルかつリアルタイム指向 のサービスを、async/await を活かして構築できます。

まさぴょん🐱まさぴょん🐱

WSGI (Web Server Gateway Interface) とは?

WSGI は “Python 製 Web アプリケーション” と “Web サーバー” をつなぐための公式インターフェース仕様 です(PEP 333 → PEP 3333)。アプリの実装をサーバー依存にしないための“共通規格コネクター”と覚えると分かりやすいでしょう。


背景と目的

課題 (2000 年代初頭) WSGI が与えた解決
各フレームワークがサーバー固有 API を直接呼び出し、移植が困難 フレームワーク=アプリHTTP サーバー を疎結合化
CGI / FastCGI ではプロセス生成コストや柔軟性が不足 永続プロセス + 高速化(マルチスレッド/マルチプロセス)
標準ライブラリだけで完結する軽量仕様が欲しい dict + callable だけで成立する最小設計

仕様の核心

def application(environ, start_response):
    status = "200 OK"
    headers = [("Content-Type", "text/plain; charset=utf-8")]
    start_response(status, headers)
    return [b"Hello WSGI!"]          # イテラブルを返す
要素 内容
environ リクエスト情報を収めた 辞書 (dict)
CGI 変数に準じたキー (REQUEST_METHOD, PATH_INFO, など) と、サーバー固有キー (wsgi.*) を含む。
start_response(status, headers, exc_info=None) ステータスラインとレスポンスヘッダーをサーバーへ伝える“コールバック”関数。
戻り値 イテラブル (list, generator など) にし、bytes を順次 yield してボディを送信。

同期関数 が前提で、async def は想定外(ここが ASGI との大きな違い)。


典型的なスタック

┌───────────────────┐
│  WSGI Application │ 例: Django, Flask, Bottle
└─────────┬─────────┘
          │ WSGI Call 単純関数
┌─────────▼─────────┐
│  WSGI Server      │ 例: Gunicorn, uWSGI, Waitress
└─────────┬─────────┘
          │ HTTP over sockets
┌─────────▼─────────┐
│   OS / Kernel      │
└───────────────────┘
  • アプリ側:フレームワークや自作アプリは “application(environ, start_response)” の形に従うだけ
  • サーバー側:リクエストを受けて environ を作り、アプリ callable を呼び出す

ミニマル実行デモ

pip install "gunicorn>=21" flask
# app.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def index():
    return "Hello from Flask over WSGI!"
# WSGI サーバー起動
gunicorn app:app --bind 0.0.0.0:8000  # ここで Flask は WSGI “アプリ”

WSGI の利点と限界

利点 限界
互換性 サーバー・フレームワークの“差し替え”が簡単 -
シンプルさ dict + callable というミニマル API 構造化が粗く手動でのバイト管理が煩雑
同期処理向き バッチ的リクエスト/レスポンスには十分 長時間接続・双方向通信は不可
成熟エコシステム Gunicorn, uWSGI, mod_wsgi など実績豊富 非同期 IO を活かすには不向き

ASGI との対照(ざっくり再掲)

観点 WSGI ASGI
コール形式 def app(environ, start_response) async def app(scope, receive, send)
対応プロトコル HTTP HTTP・WebSocket・SSE 等
同期/非同期 同期前提 非同期 (asyncio) + 同期併用可
長時間接続 不可 可能
主な利用例 伝統的 Web サイト、REST API リアルタイム API、AI ストリーム、チャット

まとめ

  • WSGI は「Python Web の基本仕様」 として 15 年以上使われ続け、Django や Flask など膨大な資産が存在
  • 課題:リアルタイム通信・高同時接続には設計上不向き
  • 現在:同期処理の安定基盤として残りつつ、リアルタイム要件には ASGI へ移行/併用するのが主流

WSGI の理解は、既存 Web 資産の保守や、ASGI との棲み分け戦略を考える上でも欠かせない基礎知識です。