Make組ブログ

Python、Webサービスや製品開発、ライブラリー開発についてhirokikyが書きます

WSGIアプリケーションとは?WebフレームワークからWSGIサーバーまで

まえがき

このブログ記事は、ある大きなドキュメントの一部のために書いています。 WSGIを説明している記事やドキュメント、本はたくさんあるので、このブログ記事で新しく説明されることはありません。

本文

PythonのWebアプリケーションは WSGI という仕様に則って開発されています。 WSGIに則って作られたWebアプリケーション(WSGIアプリケーション)は、WSGIの仕様に則ったサーバー(WSGIサーバー)上で動作させられます。

例えばPython製WebフレームワークのDjangoやFlaskはWSGIの仕様に則っています。 これらのWebフレームワークで作ったWebアプリケーションは、WSGIサーバーで動作させられます。 メジャーなPython製のWebフレームワークはWSGIアプリケーションとして作られているので、WSGIを意識する機会は少ないでしょう。

WSGIで動作するWebフレームワーク:

https://wsgi.readthedocs.io/en/latest/frameworks.html

WSGIサーバー:

https://wsgi.readthedocs.io/en/latest/servers.html

WSGIについて詳しくは wsgi.org を読むと良いでしょう。

http://wsgi.org/

極論、WSGIは気にしなくて良い

極論を言い切ってしまえば、WSGはWebフレームワークやサーバーの開発者のためのものです (もちろんピュアWSGIでWebアプリケーションを開発することもできます)。

単に「Webアプリケーションを作りたいな」という人は、そこまで深く知る必要はありません。 以下の1つだけを覚えておくと良いでしょう

  • WSGIサーバーを使えば、Python製のWebフレームワークで作ったアプリケーションを動かせる

ですが、簡単にでも役割や仕組みを知っておけばエラーに遭遇したとき理解が早くなるでしょう。 WSGIサーバーのドキュメントを読む際などにも混乱することが減りますので、簡単にここで説明します。

WSGIアプリケーションを作ってみよう

WSGIという仕様」というと難しいように感じられますが、とても簡単な仕様です。 例えば以下のPythonの関数はWSGIアプリケーションです。

def my_wsgi_app(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    body = "Method was {env['REQUEST_METHOD']}".format(env=environ)
    return [body.encode('utf-8')]

「本当にこれがWebアプリケーション?」というような関数ですが、WSGIアプリケーションです。 この関数を動作させて、ブラウザーでアクセスすると以下のように画面に表示されます。

f:id:hirokiky:20180930182908p:plain

関数の意味は何でしょうか。 それぞれ関数の引数と戻り値は以下のような仕様になっています。

  • environ: HTTPリクエストの情報(ヘッダーの値など)
  • start_response: HTTPレスポンスのコード、返すヘッダーを指定して呼び出すための関数
  • 戻り値: HTTPのボディーになるバイト型のイテラブル

この仕様を満たす関数を作れば、それはWSGIアプリケーションです。 WSGIアプリケーションはWSGIサーバーで動作させられます。 試しにこの関数を gunicorn というWSGIサーバーで動かしましょう。

my_wsgi.py という名前のファイルを作って、ファイルに上記の関数を書いているとします。 gunicornpip でインストールすると、ターミナルからサーバーを起動できます (gunicornのインストール方法などは他で説明します)。

$ gunicorn my_wsgi:wsgi_app

この my_wsgi:wsgi_app という引数は、 my_wsgi.py ファイル内の wsgi_app というWSGIアプリケーションを起動しろという意味です。 ここでブラウザーから http://127.0.0.1:8000/ にアクセスすると、画面には Method was GET と先程のように表示されます。

フレームワークWSGI

DjangoやFlaskのようなWebフレームワークは、ユーザーの書いたView関数やURLのディスパッチャーを読み込んで、呼び出し可能オブジェクトを作ります。 呼び出し可能オブジェクトとは foo() のように呼び出せるオブジェクトで、先程の wsg_app 関数も呼び出し可能オブジェクトです。

この呼び出し可能オブジェクトが、WSGIアプリケーションです。WSGIサーバーはこのWSGIアプリケーションを読み込んで、ブラウザーなどにHTTPを通して結果を返します。

  • ブラウザー: HTTPでサーバーと通信する
  • WSGIサーバー: HTTPの解釈、WSGIアプリケーションを呼び出し、結果をHTTPで返すサーバー
  • WSGIアプリケーション: 上記仕様でHTTPの内容を返すPythonの呼び出し可能オブジェクト
  • Python)Webフレームワーク: Viewなど一部の処理を書くだけでWebアプリケーションが作れるPythonパッケージ
    • ユーザーの書いたViewなどを読み込んで、WSGIアプリケーションとして動作する

このように、WSGIという仕様でPython製Webアプリケーションは作られています。 Python製のWebフレームワークでWebアプリケーションを作ったときは、WSGIサーバーで動作させれば良いと覚えておきましょう。