Web Server Gateway Interface
表示
Web Server Gateway Interface (WSGI; ウィスキー[1][2]) は、プログラミング言語Pythonにおいて、WebサーバとWebアプリケーション︵あるいはWebアプリケーションフレームワーク︶を接続するための、標準化されたインタフェース定義である。また、WSGIから着想を得て、他の言語でも同様のインタフェースが作られた。
基本的な発想[編集]
過去において、Pythonに多種のWebアプリケーションフレームワークが存在することは、PythonでWebアプリケーションを開発しようとする者にとって問題になっていた。というのも、Webアプリケーションフレームワークを選択することによって、使用できるWebサーバが制限されてしまったり、その逆の制限が発生したりしたためである。Pythonで書かれたWebアプリケーションは、FastCGI, mod_python, CGI, さらにはWebサーバ独自のAPIを使ったものなど、様々な方法で実装されていた。 この問題を解決するためにWSGIが考案された。WSGIは、Pythonにおける、WebアプリケーションとWebサーバを接続する標準仕様を定めるものである。これによって、WSGIに対応したWebアプリケーション︵やフレームワーク︶は、WSGIに対応した任意のWebサーバ上で運用できるようになる。つまり、アプリケーション側がWSGIに対応していれば、アプリケーションのコードに修正を加えることなく、WSGI対応サーバを自由に選択することができ、高い可搬性︵ポータビリティ︶が得られる。仕様の概要[編集]
WSGIには二つの側 — サーバ側とアプリケーション側が存在する。WSGIは、リクエスト情報・レスポンスヘッダ・レスポンス本文を、両者の間でどのようにやりとりするかをPythonのAPIとして定義している。 Webサーバにリクエストが来ると、次のような流れでやりとりが行なわれる‥ (一)サーバ側が、クライアントからリクエストを受ける。 (二)サーバ側は、アプリケーション側がエントリポイントとして提供するcallableオブジェクト︵関数やクラスインスタンスなど_
_call__
が定義されたオブジェクト︶を呼び出して、その引数として環境変数と1つのコールバック用callableオブジェクトを渡す。
(三)アプリケーション側は、このコールバック用callableオブジェクトを呼び出すことでステータスコードとレスポンスヘッダをサーバ側に伝え、さらに本文を生成するiterableオブジェクト︵イテレータやリストなど︶を戻り値として返す。
(四)サーバ側は、これらを用いてクライアントへのレスポンスを生成する。
WSGIはミドルウェアの考え方も提供できる。WSGIミドルウェアは、サーバ側とアプリケーション側のWSGIインタフェースを実装しているため、WSGIサーバとWSGIアプリケーションの"中間に"挿入できる。ミドルウェアはサーバーの視点からはアプリケーションとして振る舞い、アプリケーションの視点からはサーバーとして振る舞う。
"ミドルウェア"は、例えば以下のような機能を提供できる:
●目標の URL にもとづき、環境変数を適宜変更し、リクエストを別のアプリケーションのオブジェクトに回送する
●複数のアプリケーション︵やフレームワーク︶が同じプロセスの中に同居して動作できるようにする
●リクエストとレスポンスをネットワーク上で転送することによる負荷分散と遠隔処理
●コンテンツの後処理の実行 — XSLスタイルシートを適用するなど
WSGIアプリケーションの例[編集]
既存のWSGI対応フレームワークを使用する場合は意識する必要はないが、ゼロからWSGIアプリケーションを作る場合は以下の例︵Hello Worldアプリケーション︶のようにする‥def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
yield b'Hello World\n'
解説:
●WSGIアプリケーションは、callableオブジェクト (
_
_call__
が定義されたオブジェクト) として定義する︵この例では application
関数︶。このオブジェクトが呼び出される際、引数 environ
としてCGIと同様の環境変数が渡され、引数 start_response
として、ステータスコードとレスポンスヘッダを受け取るcallableオブジェクトが渡される。
●start_response
を呼び出して、ステータスコードとレスポンスヘッダを設定する。
●WSGIアプリケーションの戻り値は、本文を生成するiteratableオブジェクトである必要がある。この例ではPythonのジェネレータ機能を使ってそれを実現している。
WSGI 互換のWebアプリケーションフレームワーク[編集]
WSGIをサポートするWebアプリケーションフレームワークは多数存在する。その一例を示す: ●BlueBream ●Bottle ●CherryPy ●Django ●Flask ●Google App Engine ●Pylons ●Pyramid ●Tornado (www.tornadoweb.org) ●Trac (trac.edgewall.org) ●TurboGears ●web.py [1] ●web2py ●Werkzeug ●Zope (バージョン3以降)WSGI対応サーバ[編集]
WSGIサーバ︵WSGIアプリケーションコンテナ︶は、WSGIアプリケーションを常駐させ、HTTPクライアントからリクエストを受け取るごとに、WSGIアプリケーションのcallableオブジェクトを呼び出す。これによって、クライアントからのリクエストがアプリケーションに転送される。 WSGIアプリケーションコンテナの例としては、uWSGI, Gunicorn, Apacheモジュール (mod_wsgi, mod_pythonなど), Microsoft IIS︵isapi-wsgi, PyISAPIe, ASPゲートウェイを使用︶などがある。 さらに、WSGIアプリケーションをラップすることで、FastCGIやSCGI環境で動作させることもできるし、古典的なCGIとして動作させることもできる︵例えば、Python標準ライブラリに含まれるwsgiref.handlers.CGIHandler
が利用できる︶。
他のプログラミング言語への影響[編集]
WSGIから着想を得て、他のプログラミング言語にも同様のインターフェイスが作られた。以下はその一例である。 ●PSGI (Perl Web Server Gateway Interface) ●Rack (Ruby Web Server Interface) ●SCGI ●Ring[要曖昧さ回避] (Clojure) ●Clack (Common Lisp) ●WAI (Haskell, Web Application Interface)WSGIとPython 3[編集]
Python 3において文字列とバイト列が分離されたことはWSGIにとって問題となった。HTTPヘッダのデータはテキストとして扱われたりバイナリとして扱われたりするが、WSGIはヘッダデータを文字列として扱っている。Python 2ではテキストもバイナリも﹁文字列﹂として扱っていたためこれで問題がなかったが、Python 3ではバイナリはbytes型で扱うことになり、﹁文字列﹂とはUnicode文字列のことを表すようになった。この問題に対処した更新版のWSGI仕様は、PEP 3333として公開されている。 再考されたWSGI仕様として Web3 というものも提案されており、こちらはPEP 444 として公開されている。Web3は、互換性のないWSGIの派生であり、Python 2.6以降および3.1以降で動作するように設計されている。脚注[編集]
- ^ “An Introduction to Web Programming with WSGI”. 2007年11月閲覧。
- ^ Edge, Jake (2019年9月). “Mucking about with microframeworks”. LWN .
外部リンク[編集]
- PEP 333 -- Python Web Server Gateway Interface v1.0 インターフェイス標準の最初の定義 (英語)
- PEP 333: Python Web Server Gateway Interface v1.0 (日本語訳)
- PEP 3333 -- Python Web Server Gateway Interface v1.0.1 インターフェイス標準の定義 (英語)
- PEP 3333: Python Web Server Gateway Interface v1.0.1 (日本語訳)
- WSGI のすべてにわたる分かりやすい wiki (英語)