ホームページ  >  記事  >  バックエンド開発  >  ボトルソースコード読解メモ(1):WSGI

ボトルソースコード読解メモ(1):WSGI

巴扎黑
巴扎黑オリジナル
2017-06-23 15:06:292399ブラウズ

はじめに

Bottle は Python Web フレームワークです。フレームワーク全体には 4,000 行未満のコードが 1 つしかなく、Python 標準ライブラリ以外に依存関係はありませんが、ルーティング、テンプレート、プラグインなどの Web フレームワークの共通機能が含まれています。 Web フレームワークとは何か、それがどのように機能するかを理解するには、Bottle のソース コードを読むのが最適です。 Bottle は WSGI をサポートするフレームワークですので、ソースコードを読む前に、まず WSGI とは何かを理解しましょう。

注: この記事で使用されている Bottle のバージョンは 0.12.13 です。

WSGI

一般的なWebサーバーは静的なページしか扱えません。動的コンテンツが関係する場合、サーバーは Java/Python/Ruby などのサーバー言語と対話し、処理のためにコンテンツをそれらの言語に渡す必要があります。ほとんどの Web サーバーは C で記述されているため、サーバー言語を直接実行できないため、この 2 つの間にブリッジが必要になります (実際のアプリケーションでは、通常、WSGI をサポートするために Web サーバーと WSGI アプリケーションの間にアプリケーション サーバーが追加されます)。 Python では、WSGI がそのようなブリッジです。 WSGI の実装は 2 つの部分に分かれており、1 つはサーバー、もう 1 つはアプリケーションです。それぞれがどのようなものなのか、そして 2 つがどのように連携するのかを見てみましょう。

 1 class Server: 2  3     def __init__(self, server_address): 4         self.server_address = server_address 5  6     def set_app(self, application): 7         self.app = application 8  9     def serve_forever(self):10         while True:11             # socket.accept()12             if request_comein():13                 self.handle_request()14 15     def handle_request(self):16         request_data = self.get_request()17         self.parse_request(request_data)18         environ = self.get_environ()19         result = self.application(environ, self.start_response)20         self.send_response(result)21 22     def start_response(self, status, headers, exc_info):23         pass24 25     def get_environ(self):26         pass27 28     def get_request(self):29         pass30 31     def parse_request(self, text):32         pass33 34     def send_response(self, message):35         pass36 37 38 def make_server(host, port, app, server=Server):39     server = server((host, port))40     server.set_app(app)41     return server42 43 def simple_app(environ, start_response):44     status = '200 OK'45     response_headers = [('Content-type', 'text/plain')]46     start_response(status, response_headers)47     return 'Hello World!'48 49 if __name__ == '__main__':50     server = make_server('localhost', 8080, simple_app)51     server.serve_forever()

このサーバー モデルではスペースが限られているため、多くの詳細が省略されています。シンプルで実行可能な WSGI サーバーが必要な場合は、「Web サーバーを構築しましょう。パート 2」を参照してください。

リクエストを受信した後、サーバーはリクエスト メッセージ内の情報を解析し、結果を environ という名前の辞書に保存します。次に、environ とヘッダー情報をパラメータとして処理する start_response 関数を指定して、アプリケーション application(environ, start_response) が呼び出されます。最後に、アプリケーションの結果は新しい応答を構成してクライアントに送り返されます。

アプリケーションに関して言えば、WSGI アプリケーションは呼び出し可能なオブジェクトです。関数、メソッド、クラス、または __call__ メソッドを含むインスタンスにすることができます。上記のアプリケーションは関数です。

WSGI 標準に従ってさまざまなサーバーやアプリケーション/フレームワークを開発すると、ニーズに応じて異なるサーバーやフレームワークを自由に組み合わせることができます。

Bottle の最も単純なアプリケーション

WSGI を簡単に理解した後、Bottle に戻り、Bottle アプリケーションがどのようなもので、どのように実行され、モデルとどのように異なるかを観察します。

1 from bottle import Bottle, run2 3 app = Bottle()4 5 @app.route('/hello')6 def hello():7     return 'Hello World!'8 9 run(app, host='localhost', port=8080, server='wsgiref')

次に、このプログラムを実行し、ブラウザを使用してアドレス「localhost:8080/hello」にアクセスすると、「Hello World!」が表示されます。

1. 上記のアプリケーションとは異なり、Bottle アプリケーションはインスタンスです。 WSGI の規定によれば、Bottle オブジェクトは __call__ メソッドを実装する必要があります:

1 def __call__(self, environ, start_response):2     ''' Each instance of :class:'Bottle' is a WSGI application. '''3     return self.wsgi(environ, start_response)

したがって、この Bottle.wsgi メソッドは、サーバーが Bottle アプリケーションを呼び出すための入り口であり、私たちがボトル アプリケーションを読み取るための入り口でもあります。ソースコード。

2. @app.route() このデコレーターは関数を URL にバインドします。 「localhost:8080/hello」にアクセスすると、hello関数が呼び出されます。

3. Bottle のデフォルトサーバーは wsgiref (Python 標準ライブラリの WSGI の単純な実装) です。もちろん、Bottle は多くのサーバー用のアダプターも作成しています。サーバーの値を変更するだけで、run() 関数がサーバーの名前に基づいて対応するアダプターを見つけます。追加のコードを記述する必要はありません。

run関数とアダプターの部品コード:

 1 def run(app=None, server='wsgiref', host='127.0.0.1', port=8080, 2         interval=1, reloader=False, quiet=False, plugins=None, 3         debug=None, **kargs): 4     if server in server_names: 5         server = server_names.get(server) 6     if isinstance(server, basestring): 7         server = load(server) 8     if isinstance(server, type): 9         server = server(host=host, port=port, **kargs)10     if not isinstance(server, ServerAdapter):11         raise ValueError("Unknown or unsupported server: %r" % server)12     ...13     server.run(app)14 15 class MeinheldServer(ServerAdapter):16     def run(self, handler):17         from meinheld import server18         server.listen((self.host, self.port))19         server.run(handler)

最後に

この記事では、WSGI標準の下でサーバーとアプリケーションがどのように対話するかを簡単に紹介します。次の記事では、引き続きこの最も単純なアプリケーションに焦点を当て、@app.route() に関連するルーティング関数について説明します。

以上がボトルソースコード読解メモ(1):WSGIの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。