Web Server Gateway Interface
Web Server Gateway Interface (WSGI; ウイスキー) は、WebサーバとWebアプリケーション(またはWebフレームワーク)を接続するための簡潔かつ統一されたインタフェース定義である。プログラミング言語Pythonで使われる。
基本的な発想
歴史的に、Python に存在する多種のWebアプリケーションフレームワークは、新規のPythonユーザーにとって問題になっていた。というのも、Webフレームワークを選択することによって、使用できるWebサーバが制限されてしまったり、その逆の制限があったりしたためである。Pythonアプリケーションは、CGI, FastCGI, mod_python, さらにはWebサーバ独自のAPIを使ったもの、などのいずれかとして設計されることが多かった。
この問題を解決するためにWSGIが作られた。WSGIは、可搬性のあるWebアプリケーション開発の基盤を形成するために、WebサーバとWebアプリケーション(もしくはWebフレームワーク)を接続する簡潔かつ統一された低水準インタフェースを定めるものである。これにより、WSGIに対応したWebアプリケーション(またはWebフレームワーク)は、WSGIに対応した任意のWebサーバ上で実行できる。
仕様の概要
WSGIインターフェイスには二つの側がある。"サーバ"(もしくは"ゲートウェイ")側と、"アプリケーション"(もしくは"フレームワーク")側である。サーバー側はアプリケーション側が提供する呼び出し可能なオブジェクト(関数やクラスインスタンスなど__call__
が定義されたオブジェクト)を呼び出して、引数として環境変数とコールバック関数を渡す。アプリケーション側はこのコールバック関数を呼び出すことでステータスコードとレスポンスヘッダをサーバ側に伝え、さらに本文を生成するイテレータを戻り値として返す。
WSGIはミドルウェアの考え方も提供する。WSGIミドルウェアは、サーバ側とアプリケーション側のWSGIインタフェースを実装しているので、WSGIサーバーとWSGIアプリケーションの"中間に"挿入できる。ミドルウェアはサーバーの視点からはアプリケーションとして動作し、アプリケーションの視点からはサーバーとして動作する。
"ミドルウェア"は以下のような機能を提供できる:
- 目標の URL にもとづき、環境変数を適宜変更し、リクエストを別のアプリケーションのオブジェクトに回送する
- 複数のアプリケーション(やフレームワーク)が同じプロセスの中に同居して動作できるようにする
- リクエストとレスポンスをネットワーク上で転送することによる負荷分散と遠隔処理
- コンテンツの後処理の実行 — XSLスタイルシートを適用するなど
アプリケーションの例
既存のフレームワークを使用する場合は意識しなくてもよいが、ゼロからWSGIアプリケーションを作る場合は以下の例(Hello Worldアプリケーション)のようにする:
def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
yield 'Hello World\n'
解説:
- WSGIアプリケーションは、呼び出し可能オブジェクト (
__call__
が定義されたオブジェクト) として定義する(この例ではapplication
関数)。このcallableには、引数environ
としてCGIと同じ環境変数が渡され、引数start_response
として、ステータスコードとレスポンスヘッダを受け取る呼び出し可能オブジェクトが渡される。 start_response
を呼び出して、ステータスコードとレスポンスヘッダを設定する。- WSGIアプリケーションの戻り値は、本文を生成するiterableなオブジェクトである必要がある。この例ではPythonのジェネレータを使ってそれを実現している。
WSGI 互換のWebアプリケーションフレームワーク
WSGIをサポートするWebアプリケーションフレームワークは多数存在する。その一例を示す:
- BlueBream
- Bottle
- CherryPy
- Django
- Flask
- Google App Engine
- Pylons
- Pylamid
- Tornado (www.tornadoweb.org)
- Trac (trac.edgewall.org)
- TurboGears
- web.py [1]
- web2py
- Werkzeug
- Zope (バージョン3以降)
ラッパー
サーバーやゲートウェイは、HTTPクライアントからリクエストを受け取るごとにアプリケーション (application callable) を呼び出す。これにより、リクエストがアプリケーションに転送される。
現在、FastCGI, SCGI, uWSGI, CGI, Apache (mod_wsgi, mod_pythonを使用), AJP (flupを使用), Microsoft IIS(isapi-wsgi, PyISAPIe, ASPゲートウェイを使用)などのラッパーが利用可能である。
類似のインタフェース
WSGIの影響を受けて、他のプログラミング言語にも同様のインターフェイスが作られた。以下はその一例である。
- PSGI/Plack (Perl Web Server Gateway Interface)
- Rack (Ruby Web Server Interface)
- SCGI
WSGIとPython 3
Python 3において文字列とバイト列が分離されたことはWSGIにとって問題となった。ヘッダデータはテキストとして扱われたりやバイナリとして扱われたりするが、WSGIはヘッダデータを文字列として扱っている。Python 2ではテキストもバイナリも文字列として扱っているためこれで問題がなかった、しかしPython 3では、バイナリはbytes型で扱い、「文字列」はUnicode文字列のことを表すようになった。この問題に対処した更新版のWSGI仕様は、PEP 3333として公開されている。
再考されたWSGI仕様として Web3 というものも提案されており、これはPEP 444 として公開されている。これは互換性のないWSGIの派生であり、Python 2.6以降, 3.1以降で動作するように設計されている。
外部リンク
- PEP 333 インターフェイス標準の定義(英語)
- PEP333-ja インターフェイス標準の定義(日本語訳)
- WSGI メタフレームワーク(英語)
- WSGI のすべてにわたる分かりやすい wiki(英語)