Python | WSGI Server Introduction
WSGI サーバー入門
WSGI のインターフェイス定義は非常にシンプルです。Web 開発者は HTTP リクエストを処理する関数を 1 つ実装するだけで済みます。最もシンプルな Web 版「Hello, web。」を見てみましょう。
def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return '
上記の application() 関数は、WSGI 標準に準拠した HTTP 処理関数で、2 つのパラメータを受け取ります。
environ:すべての HTTP リクエスト情報を含むディクショナリオブジェクト。
start_response:HTTP レスポンスを送信する関数。
application() 関数内で、次のように呼び出します。
start_response('200 OK', [('Content-Type', 'text/html')])
これにより HTTP レスポンスのヘッダーが送信されます。ヘッダーの送信は 1 回のみ、つまり start_response() 関数の呼び出しも 1 回だけである点に注意してください。start_response() 関数は 2 つのパラメータを受け取ります。1 つは HTTP レスポンスコード、もう 1 つはリストで表される HTTP ヘッダーの集合で、各ヘッダーは 2 つの文字列を含むタプルで表されます。
通常、Content-Type ヘッダーをブラウザに送信する必要があります。その他、一般的に使用される HTTP ヘッダーも多く送信すべきです。
その後、関数の戻り値である '
WSGI では、environ ディクショナリオブジェクトから HTTP リクエスト情報を取得し、HTML を構築して、start_response() でヘッダーを送信し、最後にボディを返すことが注目点となります。
application() 関数自体には HTTP の解析に関する処理は一切含まれていません。つまり、低レベルのコードを自分で書く必要はなく、より高いレベルでリクエストへの処理方法を考えることに専念できます。
application() 関数はどのように呼び出されるのでしょうか。自分たちで呼び出す場合、environ と start_response の 2 つのパラメータを提供できず、戻り値の文字列をブラウザに送信することもできません。
そのため、application() 関数は WSGI サーバーによって呼び出される必要があります。WSGI 仕様に準拠するサーバーは多数存在し、その中から選択できます。しかしここでは、書いた application() 関数がブラウザに HTML を出力できるかをすぐに確認したいので、最もシンプルな WSGI サーバーを見つけて Web アプリケーションを実行します。
Python には WSGI サーバーがビルトインされています。このモジュールは wsgiref と呼ばれ、純粋な Python で書かれた WSGI サーバーのリファレンス実装です。「リファレンス実装」とは、その実装が WSGI 標準に完全に準拠しているものの、運用効率は考慮されておらず、開発およびテスト目的にのみ使用されることを意味します。
例:
from wsgiref.simple_server import make_server
# demo_app は2つのパラメータを受け取ります
# 第0パラメータは環境(コンピュータの環境、リクエストパスに関連する環境)を表します
# 第1パラメータはレスポンスヘッダーを返す関数です
# この関数には戻り値が必要です。戻り値はリストで、
# リストには要素が1つだけ含まれ、ブラウザに返すデータを表すバイナリです
def demo_app(environ, start_response):
# environ は多くのデータを保存するディクショナリです
# 特に重要な PATH_INFO でユーザーのアクセスパスを取得できます
start_response('200 OK', [('Content-Type', 'text/html;charset=utf8')])
return ['hello'.encode('utf8')] # ブラウザに表示されるコンテンツ
if __name__ == '__main__':
# demo_app はユーザーのリクエストを処理する関数です
httpd = make_server('', 8000, demo_app)
sa = httpd.socket.getsockname()
print("Serving HTTP on", sa[0], "port", sa[1], "...")
# ブラウザを開いて http://localhost:8000/xyz?abc にアクセスするコード
#import webbrowser
# webbrowser.open('http://localhost:8000/xyz?abc')
# 1件のリクエストを処理する
# httpd.handle_request()
httpd.serve_forever() # サーバーをバックグラウンドで継続的に実行する
カスタム WSGI サーバー
from wsgiref.simple_server import make_server
def demo_app(environ, start_response):
# environ は多くのデータを保持するディクショナリです
# 特に重要な PATH_INFO でユーザーのアクセスパスを取得できます
path = environ['PATH_INFO']
print('path={}'. format(path))
start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ('sss', 'dddd')])
return ['Hello'.encode('utf8')]
if __name__ == '__main__':
httpd = make_server('', 8080, demo_app)
sa = httpd.socket.getsockname()
print("Serving HTTP on", sa[0], "port", sa[1], "...")
httpd.serve_forever()
WSGI のインターフェイス定義は非常にシンプルです。Web 開発者は HTTP リクエストを処理する関数を 1 つ実装するだけで済みます。最もシンプルな Web 版「Hello, web。」を見てみましょう。
def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return '
Hello, web。
'上記の application() 関数は、WSGI 標準に準拠した HTTP 処理関数で、2 つのパラメータを受け取ります。
environ:すべての HTTP リクエスト情報を含むディクショナリオブジェクト。
start_response:HTTP レスポンスを送信する関数。
application() 関数内で、次のように呼び出します。
start_response('200 OK', [('Content-Type', 'text/html')])
これにより HTTP レスポンスのヘッダーが送信されます。ヘッダーの送信は 1 回のみ、つまり start_response() 関数の呼び出しも 1 回だけである点に注意してください。start_response() 関数は 2 つのパラメータを受け取ります。1 つは HTTP レスポンスコード、もう 1 つはリストで表される HTTP ヘッダーの集合で、各ヘッダーは 2 つの文字列を含むタプルで表されます。
通常、Content-Type ヘッダーをブラウザに送信する必要があります。その他、一般的に使用される HTTP ヘッダーも多く送信すべきです。
その後、関数の戻り値である '
Hello, web。
' が HTTP レスポンスのボディとしてブラウザに送信されます。WSGI では、environ ディクショナリオブジェクトから HTTP リクエスト情報を取得し、HTML を構築して、start_response() でヘッダーを送信し、最後にボディを返すことが注目点となります。
application() 関数自体には HTTP の解析に関する処理は一切含まれていません。つまり、低レベルのコードを自分で書く必要はなく、より高いレベルでリクエストへの処理方法を考えることに専念できます。
application() 関数はどのように呼び出されるのでしょうか。自分たちで呼び出す場合、environ と start_response の 2 つのパラメータを提供できず、戻り値の文字列をブラウザに送信することもできません。
そのため、application() 関数は WSGI サーバーによって呼び出される必要があります。WSGI 仕様に準拠するサーバーは多数存在し、その中から選択できます。しかしここでは、書いた application() 関数がブラウザに HTML を出力できるかをすぐに確認したいので、最もシンプルな WSGI サーバーを見つけて Web アプリケーションを実行します。
Python には WSGI サーバーがビルトインされています。このモジュールは wsgiref と呼ばれ、純粋な Python で書かれた WSGI サーバーのリファレンス実装です。「リファレンス実装」とは、その実装が WSGI 標準に完全に準拠しているものの、運用効率は考慮されておらず、開発およびテスト目的にのみ使用されることを意味します。
例:
from wsgiref.simple_server import make_server
# demo_app は2つのパラメータを受け取ります
# 第0パラメータは環境(コンピュータの環境、リクエストパスに関連する環境)を表します
# 第1パラメータはレスポンスヘッダーを返す関数です
# この関数には戻り値が必要です。戻り値はリストで、
# リストには要素が1つだけ含まれ、ブラウザに返すデータを表すバイナリです
def demo_app(environ, start_response):
# environ は多くのデータを保存するディクショナリです
# 特に重要な PATH_INFO でユーザーのアクセスパスを取得できます
start_response('200 OK', [('Content-Type', 'text/html;charset=utf8')])
return ['hello'.encode('utf8')] # ブラウザに表示されるコンテンツ
if __name__ == '__main__':
# demo_app はユーザーのリクエストを処理する関数です
httpd = make_server('', 8000, demo_app)
sa = httpd.socket.getsockname()
print("Serving HTTP on", sa[0], "port", sa[1], "...")
# ブラウザを開いて http://localhost:8000/xyz?abc にアクセスするコード
#import webbrowser
# webbrowser.open('http://localhost:8000/xyz?abc')
# 1件のリクエストを処理する
# httpd.handle_request()
httpd.serve_forever() # サーバーをバックグラウンドで継続的に実行する
カスタム WSGI サーバー
from wsgiref.simple_server import make_server
def demo_app(environ, start_response):
# environ は多くのデータを保持するディクショナリです
# 特に重要な PATH_INFO でユーザーのアクセスパスを取得できます
path = environ['PATH_INFO']
print('path={}'. format(path))
start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ('sss', 'dddd')])
return ['Hello'.encode('utf8')]
if __name__ == '__main__':
httpd = make_server('', 8080, demo_app)
sa = httpd.socket.getsockname()
print("Serving HTTP on", sa[0], "port", sa[1], "...")
httpd.serve_forever()
Related Articles
-
A detailed explanation of Hadoop core architecture HDFS
Knowledge Base Team
-
What Does IOT Mean
Knowledge Base Team
-
6 Optional Technologies for Data Storage
Knowledge Base Team
-
What Is Blockchain Technology
Knowledge Base Team
Explore More Special Offers
-
Short Message Service(SMS) & Mail Service
50,000 email package starts as low as USD 1.99, 120 short messages start at only USD 1.00
