バージョン 2.5 で追加.
Web Server Gateway Interface (WSGI) は、Web サーバソフトウェアと Python で記述された Web アプリケーションとの標準インターフェースです。標準インターフェースを持つことで、WSGI をサポートするアプリケーションを幾つもの異なる Web サーバで使うことが容易になります。
Web サーバとプログラミングフレームワークの作者だけが、WSGI デザインのあらゆる細部や特例などを知る必要があります。WSGI アプリケーションを インストールしたり、既存のフレームワークを使ったアプリケーションを記述するだけの皆さんは、全てについて理解する必要はありません。
wsgiref は WSGI 仕様のリファレンス実装で、これは Web サーバやフレームワークに WSGI サポートを加えるのに利用できます。 これは WSGI 環境変数やレスポンスヘッダを操作するユーティリティ、 WSGI サーバ実装時のベースクラス、WSGI アプリケーションを提供する デモ用 HTTP サーバ、それと WSGI サーバとアプリケーションの WSGI 仕様 (PEP 333) 準拠のバリデーションツールを提供します。
http://www.wsgi.org に、WSGIに関するさらなる情報と、チュートリアルやその他のリソースへのリンクがあります。
このモジュールは WSGI 環境で使う様々なユーティリティ関数を提供します。 WSGI 環境は PEP 333 で記述されているような HTTP リクエスト変数を含む辞書です。全ての environ パラメタを取る関数は WSGI 準拠の辞書を与えられることを期待しています;細かい仕様については PEP 333 を参照してください。
wsgi.url_scheme が “http” か “https” かについて、 environ 辞書の HTTPS 環境変数を調べることでその推測を返します。戻り値は文字列(string)です。
この関数は、CGI や FastCGI のような CGI に似たプロトコルをラップするゲートウェイを作成する場合に便利です。典型的には、それらのプロトコルを 提供するサーバが SSL 経由でリクエストを受け取った場合には HTTPS 変数に値 “1” “yes”、または “on” を持つでしょう。ですので、この関数はそのような値が見つかった場合には “https” を返し、そうでなければ “http” を返します。
クエリ文字列をオプションで含むリクエスト URI 全体を、 PEP 333 の “URL 再構築(URL Reconstruction)” にあるアルゴリズムを使って返します。 include_query が false の場合、クエリ文字列は結果となる文字列には含まれません。
request_url() に似ていて、 PATH_INFO と QUERY_STRING 変数は 無視されます。結果はリクエストによって指定されたアプリケーションオブジェクトのベース URI です。
PATH_INFO から SCRIPT_NAME まで一つの名前をシフトしてその名前を返します。 environ 辞書は 変更されます ; PATH_INFO や SCRIPT_NAME のオリジナルをそのまま残したい場合にはコピーを使ってください。
PATH_INFO にパスセグメントが何も残っていなければ、 None が返されます。
典型的なこのルーチンの使い方はリクエスト URI のそれぞれの要素の処理で、例えばパスを一連の辞書のキーとして取り扱う場合です。 このルーチンは、渡された環境を、ターゲット URL で示される別の WSGI アプリケーションの呼び出しに合うように調整します。例えば、 /foo に WSGI アプリケーションがあったとして、そしてリクエスト URL パスが /foo/bar/baz で、 /foo の WSGI アプリケーションが shift_path_info() を呼んだ場合、これは “bar” 文字列を受け取り、環境は /foo/bar の WSGI アプリケーションへの受け渡しに適するように更新されます。つまり、 SCRIPT_NAME は /foo から /foo/bar に変わって、 PATH_INFO は /bar/baz から /baz に変化するのです。
PATH_INFO が単に “/” の場合、このルーチンは空の文字列を返し、 SCRIPT_NAME の末尾にスラッシュを加えます、これはたとえ 空のパスセグメントが通常は無視され、そして SCRIPT_NAME は通常スラッシュで終わる事が無かったとしてもです。これは意図的な振る舞いで、 このルーチンでオブジェクト巡回(object traversal) をした場合に /x で終わる URI と /x/ で終わるものを アプリケーションが識別できることを保証するためのものです。
テスト目的で、 environ を自明なデフォルト値 (trivial defaults) で更新します。
このルーチンは WSGI に必要な様々なパラメタを追加し、それには HTTP_HOST 、 SERVER_NAME 、 SERVER_PORT 、 REQUEST_METHOD 、 SCRIPT_NAME 、 PATH_INFO 、あとは PEP 333 で定義されている wsgi.* 変数群を含みます。これはデフォルト値のみを追加し、これらの変数の既存設定は一切置きかえません。
このルーチンは、ダミー環境をセットアップすることによって WSGI サーバとアプリケーションのユニットテストを容易にすることを意図しています。これは実際の WSGI サーバやアプリケーションで使うべきではありません。なぜならこのデータは偽物なのです!
利用例:
from wsgiref.util import setup_testing_defaults
from wsgiref.simple_server import make_server
# 比較的シンプルなWSGIアプリケーション。
# setup_testing_defaults によって更新されたあとの environment を表示する
def simple_app(environ, start_response):
setup_testing_defaults(environ)
status = '200 OK'
headers = [('Content-type', 'text/plain')]
start_response(status, headers)
ret = ["%s: %s\n" % (key, value)
for key, value in environ.iteritems()]
return ret
httpd = make_server('', 8000, simple_app)
print "Serving on port 8000..."
httpd.serve_forever()
上記の環境用関数に加えて、 wsgiref.util モジュールも以下のようなその他のユーティリティを提供します:
‘header_name’ が RFC 2616 で定義されている HTTP/1.1 の “Hop-by-Hop” ヘッダの場合に true を返します。
ファイルライクオブジェクトをイテレータ(iterator)に変換するラッパです。結果のオブジェクトは __getitem__() と __iter__() 両方をサポートしますが、これは Python 2.1 と Jython の互換性のためです。オブジェクトがイテレートされる間、オプションの blksize パラメタがくり返し filelike オブジェクトの read() メソッドに渡されて 受け渡す文字列を取得します。 read() が空文字列を返した場合イテレーションは終了して、再開されることはありません。
filelike に close() メソッドがある場合、返されたオブジェクトも close() メソッドを持ち、これが呼ばれた場合には filelike オブジェクトの close() メソッドを呼び出します。
利用例:
from StringIO import StringIO
from wsgiref.util import FileWrapper
# We're using a StringIO-buffer for as the file-like object
filelike = StringIO("This is an example file-like object"*10)
wrapper = FileWrapper(filelike, blksize=5)
for chunk in wrapper:
print chunk
このモジュールは単一のクラス、 Headers を提供し、WSGI レスポンスヘッダの操作をマップに似たインターフェースで便利にします。
headers をラップするマップに似たオブジェクトを生成します。これは PEP 333 に定義されるようなヘッダの名前/値のタプルのリストです。 新しい Headers オブジェクトに与えられた変更は、一緒に作成された headers リストを直接更新します。
Headers オブジェクトは典型的なマッピング操作をサポートし、これには __getitem__() 、 get() 、 __setitem__() 、 setdefault() 、 __delitem__() 、 __contains__() と has_key() を含みます。これらメソッドのそれぞれにおいて、キーはヘッダ名で(大文字小文字は区別しません)、値はそのヘッダ名に関連づけられた 最初の値です。ヘッダを設定すると既存のヘッダ値は削除され、ラップされたヘッダのリストの末尾に新しい値が加えられます。既存のヘッダの順番は 一般的に整えられていて、ラップされたリストの最後に新しいヘッダが追加されます。
辞書とは違って、 Headers オブジェクトはラップされたヘッダリストに 存在しないキーを取得または削除しようとした場合にもエラーを発生しません。単に、存在しないヘッダの取得は None を返し、存在しないヘッダの削除は 何もしません。
Headers オブジェクトは keys() 、 values() 、 items() メソッドもサポートします。 keys() と items() で 返されるリストは、同じキーを一回以上含むことがあり、これは複数の値を持つヘッダの場合です。 Header オブジェクトの len() は、その items() の長さと同じであり、ラップされたヘッダリストの長さと同じです。事実、 items() メソッドは 単にラップされたヘッダリストのコピーを返しているだけです。
Headers オブジェクトに対して str() を呼ぶと、HTTP レスポンスヘッダとして 送信するのに適した形に整形された文字列を返します。それぞれのヘッダはコロンとスペースで区切られた値と共に一列に並んでいます。 それぞれの行はキャリッジリターンとラインフィードで終了し、文字列は空行で終了しています。
これらのマッピングインターフェースと整形機能に加えて、 Headers オブジェクトは複数の値を持つヘッダの取得と追加、MIME パラメタでヘッダを追加するための以下のようなメソッド群も持っています:
指定されたヘッダの全ての値のリストを返します。
返されるリストは、元々のヘッダリストに現れる順、またはこのインスタンスに追加された順に並んでいて、複製を含む場合があります。削除されて加えられた フィールドは全てヘッダリストの末尾に付きます。ある名前のフィールドが何もなければ、空のリストが返ります。
ヘッダ(複数の値かもしれません)を、キーワード引数を通じて指定するオプションの MIME パラメタと共に追加します。
name は追加するヘッダフィールドです。このヘッダフィールドに MIME パラメタを 設定するためにキーワード引数を使うことができます。それぞれのパラメタは文字列か None で なければいけません。パラメタ中のアンダースコアはダッシュに変換されます、これはダッシュが Python の識別子としては不正なのですが、多くの MIME パラメタはダッシュを含むためです。パラメタ値が文字列の場合、これはヘッダ値のパラメタに name="value" の形で追加されます。これがもし None の場合、パラメタ名だけが追加されます。(これは値なしの MIME パラメタの場合に使われます。)使い方の例は:
h.add_header('content-disposition', 'attachment', filename='bud.gif')
上記はこのようなヘッダを追加します:
Content-Disposition: attachment; filename="bud.gif"
このモジュールは WSGI アプリケーションを提供するシンプルな HTTP サーバです( BaseHTTPServer がベースです)。 個々のサーバインスタンスは単一の WSGI アプリケーションを、特定のホストとポート上で 提供します。もし一つのホストとポート上で複数のアプリケーションを提供したいならば、 PATH_INFO をパースして個々のリクエストでどのアプリケーションを呼び出すか選択するような WSGI アプリケーションを作るべきです。(例えば、 wsgiref.util から shift_path_info() を利用します。)
host と port 上で待機し、 app へのコネクションを受け付ける WSGI サーバを作成します。戻り値は与えられた server_class のインスタンスで、指定された handler_class を使ってリクエストを処理します。 app は PEP 333 で定義されるところの WSGI アプリケーションでなければいけません。
使用例:
from wsgiref.simple_server import make_server, demo_app
httpd = make_server('', 8000, demo_app)
print "Serving HTTP on port 8000..."
# プロセスが死ぬまでリクエストに答える
httpd.serve_forever()
# 代替:1つのリクエストを受けて終了する
httpd.handle_request()
この関数は小規模ながら完全な WSGI アプリケーションで、 “Hello world!” メッセージと、 environ パラメタに提供されている キー/値のペアを含むテキストページを返します。これは WSGI サーバ( wsgiref.simple_server のような)がシンプルな WSGI アプリケーションを正しく実行できるかを確かめるのに便利です。
WSGIServer インスタンスを作成します。 server_address は (host,port) のタプル、そして RequesthandlerClass はリクエストの処理に使われる BaseHTTPServer.BaseHTTPRequestHandler のサブクラスでなければいけません。
make_server() が細かい調整をやってくれるので、通常はこのコンストラクタを呼ぶ必要はありません。
WSGIServer は BaseHTTPServer.HTTPServer のサブクラスですので、 この全てのメソッド( serve_forever() や handle_request() のような)が利用できます。 WSGIServer も以下のような WSGI 固有メソッドを提供します:
呼び出し可能(callable)な application をリクエストを受け取る WSGI アプリケーションとして設定します。
現在設定されている呼び出し可能(callable)アプリケーションを返します。
しかしながら、通常はこれらの追加されたメソッドを使う必要はありません。 set_app() は普通は make_server() によって呼ばれ、 get_app() は主にリクエストハンドラインスタンスの便宜上存在するからです。
与えられた request (すなわちソケット)の HTTP ハンドラ、 client_address ( host,port) のタプル)、 server ( WSGIServer インスタンス)の HTTP ハンドラを作成します。
このクラスのインスタンスを直接生成する必要はありません;これらは必要に応じて WSGIServer オブジェクトによって自動的に生成されます。しかしながら、このクラスをサブクラス化し、 make_server() 関数に handler_class として与えることは可能でしょう。サブクラスにおいてオーバーライドする意味のありそうなものは:
リクエストに対する WSGI 環境を含む辞書を返します。デフォルト実装では WSGIServer オブジェクトの base_environ 辞書属性のコンテンツをコピーし、それから HTTP リクエスト由来の様々なヘッダを追加しています。 このメソッド呼び出し毎に、 PEP 333 に指定されている関連する CGI 環境変数を全て含む新規の辞書を返さなければいけません。
wsgi.errors ストリームとして使われるオブジェクトを返します。デフォルト実装では単に sys.stderr を返します。
HTTP リクエストを処理します。デフォルト実装では実際の WGI アプリケーションインターフェースを実装するのに wsgiref.handlers クラスを使ってハンドラインスタンスを作成します。
WSGI アプリケーションのオブジェクト、フレームワーク、サーバ又はミドルウェアの作成時には、その新規のコードを wsgiref.validate を使って準拠の検証をすると便利です。このモジュールは WSGI サーバやゲートウェイと WSGI アプリケーションオブジェクト間の通信を検証する WSGI アプリケーションオブジェクトを作成する関数を提供し、双方のプロトコル準拠をチェックします。
このユーティリティは完全な PEP 333 準拠を保証するものでないことは注意してください; このモジュールでエラーが出ないことは必ずしもエラーが存在しないことを意味しません。しかしこのモジュールがエラーを出したならば、サーバかアプリケーションの どちらかが 100 このモジュールは lan Bicking の “Python Paste” ライブラリの paste.lint モジュールをベースにしています。
application をラップし、新しい WSGI アプリケーションオブジェクトを返します。返されたアプリケーションは全てのリクエストを元々の application にフォワードし、 application とそれを呼び出すサーバの両方が WSGI 仕様と RFC 2616 の両方に準拠しているかをチェックします。
検出された非準拠は、投げられる AssertionError の中に入ります; しかし、このエラーがどう扱われるかはサーバ依存であることに注意してください。例えば、 wsgiref.simple_server とその他 wsgiref.handlers ベースのサーバ(エラー処理メソッドが他のことをするようにオーバライドしていないもの)は 単純にエラーが発生したというメッセージとトラックバックのダンプを sys.stderr やその他のエラーストリームに出力します。
このラッパは warnings モジュールを使って出力を生成し、疑問の余地はあるが実際には PEP 333 で禁止はされていないかもしれない挙動を指摘します。これらは Python のコマンドラインオプションや warnings API で 抑制されなければ、 sys.stderr (たまたま同一のオブジェクトで無い限り wsgi.errors では ない)に書き出されます。
利用例:
from wsgiref.validate import validator
from wsgiref.simple_server import make_server
# Our callable object which is intentionally not compliant to the
# standard, so the validator is going to break
def simple_app(environ, start_response):
status = '200 OK' # HTTP Status
headers = [('Content-type', 'text/plain')] # HTTP Headers
start_response(status, headers)
# This is going to break because we need to return a list, and
# the validator is going to inform us
return "Hello World"
# This is the application wrapped in a validator
validator_app = validator(simple_app)
httpd = make_server('', 8000, validator_app)
print "Listening on port 8000...."
httpd.serve_forever()
このモジュールは WSGI サーバとゲートウェイ実装のベースハンドラクラスを提供します。これらのベースクラスは CGI ライクの環境を与えられれば 入力、出力そしてエラーストリームと共に WSGI アプリケーションとの通信の大部分を処理します。
sys.stdin 、 sys.stdout 、 stderr そして os.environ 経由での CGI ベースの呼び出しです。これは、もしあなたが WSGI アプリケーションを持っていて、これを CGI スクリプトとして実行したい場合に有用です。単に CGIHandler().run(app) を起動してください。 app はあなたが起動したい WSGI アプリケーションオブジェクトです。
このクラスは BaseCGIHandler のサブクラスで、これは wsgi.run_once を true、 wsgi.multithread を false、そして wsgi.multiprocess を true にセットし、常に sys と os を、必要な CGI ストリームと環境を取得するために使用します。
CGIHandler に似ていますが、 sys と os モジュールを使う代わりに CGI 環境と I/O ストリームを明示的に指定します。 multithread と multiprocess の値は、ハンドラインスタンスにより実行されるアプリケーションの wsgi.multithread と wsgi.multiprocess フラグの設定に使われます。
このクラスは SimpleHandler のサブクラスで、HTTP の “本サーバ” でない ソフトウェアと使うことを意図しています。もしあなたが Status: ヘッダを HTTP ステータスを送信するのに使うような ゲートウェイプロトコルの実装(CGI、FastCGI、SCGIなど)を書いているとして、おそらく SimpleHandler でなくこれをサブクラス化したいことでしょう。
BaseCGIHandler と似ていますが、HTTP の本サーバと使うためにデザインされています。もしあなたが HTTP サーバ実装を書いている場合、おそらく BaseCGIHandler でなくこれをサブクラス化したいことでしょう。
このクラスは BaseHandler のサブクラスです。これは __init__() 、 get_stdin() 、 get_stderr() 、 add_cgi_vars() 、 _write() 、 _flush() をオーバーライドして、コンストラクタから明示的に環境とストリームを設定するようにしています。与えられた環境とストリームは stdin 、 stdout 、 stderr それに environ 属性に保存されています。
これは WSGI アプリケーションを実行するための抽象ベースクラスです。原理上は複数のリクエスト用に再利用可能なサブクラスを作成することが できますが、それぞれのインスタンスは一つの HTTP リクエストを処理します。
BaseHandler インスタンスは外部からの利用にたった一つのメソッドを持ちます:
指定された WSGI アプリケーション、 app を実行します。
その他の全ての BaseHandler のメソッドはアプリケーション実行プロセスで このメソッドから呼ばれます。ですので、主にそのプロセスのカスタマイズのために存在しています。
以下のメソッドはサブクラスでオーバーライドされなければいけません:
文字列の data をクライアントへの転送用にバッファします。このメソッドが実際にデータを転送しても OK です: 下部システムが実際にそのような区別をしている場合に効率をより良くするために、 BaseHandler は書き出しとフラッシュ操作を分けているからです。
現在処理中のリクエストの wsgi.input としての利用に適当な入力ストリームオブジェクトを返します。
現在処理中のリクエストの wsgi.errors としての利用に適当な出力ストリームオブジェクトを返します。
現在のリクエストの CGI 変数を environ 属性に追加します。
これらがオーバーライドするであろうメソッド及び属性です。しかしながら、このリストは単にサマリであり、オーバーライド可能な全てのメソッドは 含んでいません。カスタマイズした BaseHandler サブクラスを作成しようとする前にドキュメント文字列 (docstrings) やソースコードでさらなる情報を調べてください。
WSGI 環境のカスタマイズのための属性とメソッド:
wsgi.multithread 環境変数で使われる値。デフォルトは BaseHandler では true ですが、別のサブクラスではデフォルトで(またはコンストラクタによって設定されて)異なる値を持つことがあります。
wsgi.multiprocess 環境変数で使われる値。デフォルトは BaseHandler では true ですが、別のサブクラスではデフォルトで(またはコンストラクタによって設定されて)異なる値を持つことがあります。
wsgi.run_once 環境変数で使われる値。デフォルトは BaseHandler では false ですが、 CGIHandler はデフォルトでこれを true に設定します。
全てのリクエストの WSGI 環境に含まれるデフォルトの環境変数。デフォルトでは、 wsgiref.handlers がインポートされた時点では これは os.environ のコピーですが、サブクラスはクラスまたはインスタンスレベルでそれら自身のものを作ることができます。 デフォルト値は複数のクラスとインスタンスで共有されるため、この辞書は読み取り専用と考えるべきだという点に注意してください。
origin_server 属性が設定されている場合、この属性の値がデフォルトの SERVER_SOFTWARE WSGI 環境変数の設定や HTTP レスポンス中のデフォルトの Server: ヘッダの設定に使われます。これは( BaseCGIHandler や CGIHandler のような)HTTP オリジンサーバでないハンドラでは無視されます。
現在のリクエストで使われている URL スキームを返します。デフォルト実装は wsgiref.util の guess_scheme() を使い、現在のリクエストの envion 変数に基づいてスキームが”http” か “https” かを推測します。
environ 属性を、全てを導入済みの WSGI 環境に設定します。デフォルトの実装は、上記全てのメソッドと属性、加えて get_stdin() 、 get_stderr() 、 add_cgi_vars() メソッドと wsgi_file_wrapper 属性を利用します。これは、キーが存在せず、 origin_server 属性が true 値で server_software 属性も設定されている場合に SERVER_SOFTWARE を挿入します。
例外処理のカスタマイズのためのメソッドと属性:
exec_info タプルをサーバログに記録します。 exc_info は (type, value, traceback) のタプルです。 デフォルトの実装は単純にトレースバックをリクエストの wsgi.errors ストリームに 書き出してフラッシュします。サブクラスはこのメソッドをオーバーライドしてフォーマットを変更したり出力先の変更、トレースバックを管理者にメールしたり その他適切と思われるいかなるアクションも取ることができます。
デフォルトの log_exception() メソッドで出力されるトレースバック出力に含まれる最大のフレーム数です。 None ならば、 全てのフレームが含まれます。
このメソッドは、ユーザに対してエラーページを出力する WSGI アプリケーションです。これはクライアントにヘッダが送出される前にエラーが発生した場合にのみ 呼び出されます。
このメソッドは sys.exc_info() を使って現在のエラー情報にアクセスでき、その情報はこれを呼ぶときに start_response に 渡すべきです( PEP 333 の “Error Handling” セクションに記述があります)。
デフォルト実装は単に error_status 、 error_headers 、そして error_body 属性を出力ページの生成に使います。サブクラスではこれをオーバーライドしてもっと動的なエラー出力をすることが出来ます。
しかし、セキュリティの観点からは診断をあらゆる老練ユーザに吐き出すことは推奨されないことに気をつけてください;理想的には、診断的な出力を有効に するには何らかの特別なことをする必要があるようにすべきで、これがデフォルト実装では何も含まれていない理由です。
エラーレスポンスで使われる HTTP ヘッダです。これは PEP 333 で述べられているような、 WSGI レスポンスヘッダ(``(name, value)`` タプル)のリストであるべきです。デフォルトのリストはコンテントタイプを text/plain にセットしているだけです。
エラーレスポンスボディ。これは HTTP レスポンスのボディ文字列であるべきです。これはデフォルトではプレーンテキストで “A server error occurred. Please contact the administrator.” です。
PEP 333 の “オプションのプラットフォーム固有のファイルハンドリング” 機能のためのメソッドと属性:
wsgi.file_wrapper ファクトリ、または None です。この属性のデフォルト値は wsgiref.util の FileWrapper クラスです。
オーバーライドしてプラットフォーム固有のファイル転送を実装します。このメソッドはアプリケーションの戻り値が wsgi_file_wrapper 属性で指定されたクラスのインスタンスの場合にのみ呼ばれます。これはファイルの転送が成功できた場合には true を返して、デフォルトの転送コードが 実行されないようにするべきです。このデフォルトの実装は単に false 値を返します。
その他のメソッドと属性:
この属性はハンドラの _write() と _flush() が、特別に Status: ヘッダに HTTP ステータスを求めるような CGI 状のゲートウェイプロトコル経由でなく、クライアントと直接通信をするような場合には true 値に設定されているべきです。
この属性のデフォルト値は BaseHandler では true ですが、 BaseCGIHandler と CGIHandler では false です。
origin_server が true の場合、この文字列属性はクライアントへのレスポンスセットの HTTP バージョンの設定に使われます。デフォルトは "1.0" です。
これは動作する “Hello World” WSGIアプリケーションです。
from wsgiref.simple_server import make_server
# Every WSGI application must have an application object - a callable
# object that accepts two arguments. For that purpose, we're going to
# use a function (note that you're not limited to a function, you can
# use a class for example). The first argument passed to the function
# is a dictionary containing CGI-style envrironment variables and the
# second variable is the callable object (see PEP333)
def hello_world_app(environ, start_response):
status = '200 OK' # HTTP Status
headers = [('Content-type', 'text/plain')] # HTTP Headers
start_response(status, headers)
# The returned object is going to be printed
return ["Hello World"]
httpd = make_server('', 8000, hello_world_app)
print "Serving on port 8000..."
# Serve until process is killed
httpd.serve_forever()