Python WSGI規範紹介


Python Web開発者としては、開発段階ではWSGIという名詞には触れないのが一般的ですが、プログラム開発が完了し、オンライン展開を考えると、WSGI仕様はややこしい話題です。ここではWSGIとは何かを紹介します。
WSGIフルエンスWeb Server Gateway Interfaceは、Python言語のために定義されているWebサーバとWebアプリケーション(またはフレームワーク)との間の汎用プログラミングインターフェースである。WSGIプロトコルは、クライアントとサービス端末のデータ転送の仕様を定義しているようなプロトコルであり、WSGIプロトコルは、WebサーバとWebアプリケーションとの連携作業の仕様を定義している。
Python Webアプリケーション展開方案
FlashkやDjangoなどのWebフレームは内蔵のWeb Serverを提供しており、現地開発段階ではflashk runまたはpython manage.py runserverを使用してそれぞれFlashkまたはDjango内蔵のServerを起動することができます。
環境展開アプリケーションの製造においては、フレーム内蔵のServerは通常使われず、GnicornやuWSGIを用いて配置され、より良い性能を得ることができる。Python Webアプリケーションを展開したことがある学生は、以下のような配置アーキテクチャについて知っているはずです。左側はブラウザ、右側はサーバーです。サーバ内部では、まずNgixを通じて80/443ポートを傍受し、クライアントからの要求を受信すると、Ngixは5000ポートの監視を要求するGunicson/uWSGI Serverに転送し、次いでWSGIプロトコルを通じてFlashk/Djangoフレームに転送し、フレーム内で要求ロジックを処理して応答情報を元の経路に戻します。

Nginnxは性能が高いです。なぜNginnxにアプリケーションを直接展開しないのですか?WSGI規格に準拠していないので、Gunnicon/uWSGIのように簡単にFlashk/Djangoフレームと結合できません。
WSGI仕様
Python Webアプリケーション配置アーキテクチャにより、WSGIの位置が分かりました。次にWSGI仕様を見て、具体的にどのような内容が定義されていますか?
HTTPプロトコルのようにクライアントと一つのサービス端末があります。WSGIプロトコルにはApple端末と一つのServer端末があります。ここでAppplicationとはFlashk、DjangoのようなWebフレームを指しています。ServerとはGunicorn、uWSGIなどのWebサーバを指します。
WSGIプロトコルでは、Application端末が呼び出し可能なオブジェクト(関数、クラスなど)として実現する必要があります。そのインターフェースは以下の通りです。

def simple_app(environ, start_response):
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    return ['Hello world!
']
シンプル_appは最も簡単なAppleです。二つのパラメータを受信する必要があります。environはdictです。その中にはすべてのHTTP要求に関する情報が保存されています。Server端から提供されます。start_。レスポンスはオブジェクトを呼び出すことができますが、Server側に提供されます。app内部は一回のstart_を呼び出す必要があります。レスポンスと状態コードとレスポンスヘッダをパラメータとして渡します。アプリは最終的に、HTTP Bodyコンテンツとして反復可能なオブジェクトをクライアントに返す。
アプリ端末インターフェースはすでに分かりました。次はWSGIプロトコルに適合するServer端末の実現を見ます。

import os


def wsgi_server(application):
    environ = dict(os.environ.items())

    def start_response(status, response_headers):
        print(f'status: {status}')
        print(f'response_headers: {response_headers}')

    result = application(environ, start_response)
    for data in result:
        print(f'response_body: {data}')
例ではServer端も関数を使って実装されており、wsgi_serverはパラメータとしてアプリを受信し、その内部にenvironとstart_を構築しました。ここでは環境変数情報を用いてHTTP要求情報構造environ辞書,start_をシミュレーションします。レスポンスは同じ関数として定義されています。appicationは内部で呼び出されます。server関数は最後にアプリを呼び出して印刷します。
アプリ端末とServer端末があります。この簡単なWSGIプログラムの例をテストしてみます。シンプルを入れるだけでいいですアプリをパラメータとしてwsgi_に渡す。serverを呼び出してwsgi_serverでいいです

wsgi_server(simple_app)
以上のコードを実行すると、次のように印刷されます。

status: 200 OK
response_headers: [('Content-type', 'text/plain')]
response_body: Hello world!
以上、WSGI規格に準拠したApple端末とServer端末をそれぞれ実現しました。プログラムは簡単に見えますが、どんなに複雑なPython WebフレームとServerも同じ仕様です。
WSGI実用化
WSGI仕様を勉強しました。私たちは普段使っているPython Webフレームが本当にこの規格に従っているかどうかを検証します。ここでFlashkフレームのソースコードを例にとって、https://github.com/pallets/flask/blob/master/src/flask/app.pyでFlashkの定義を調べられます。

class Flask(Scaffold):
    ...

    def __call__(self, environ, start_response):
        """The WSGI server calls the Flask application object as the
        WSGI application. This calls :meth:`wsgi_app`, which can be
        wrapped to apply middleware.
        """
        return self.wsgi_app(environ, start_response)
Flaask類内部は、__u u_uを実現することによりコールバックこの方法により、Flashkのインスタンスオブジェクトは、WSGI Application仕様に同様に適合するインターフェースを実現する呼び出し可能なオブジェクトとなる。
以上はPython WSGI規範の紹介の詳細です。Python WSGI規格に関する資料は他の関連記事に注目してください。