Flask を理解する
1.はじめに
Flaskはjinja2,werkzengをラップして作られた軽量なWEBアプリ開発向けのフレームワークであり、下記のモジュールのインストールが必要になります。
・jinja2
・werkzeng
・click
・itsdangerous
・markupsafe
jinja2, werkzeng(依存パッケージはclick,itsdangerous,markupsafe)、この2つのライブラリを元に作られており、とてもシンプルなフレームワークです。
そこに必要な各種モジュールを取り込んで拡張可能な作りになっているため、他Pythonフレームワークと比較して軽量と言われています。
では、Flaskを構成する Jinja2, Werkzeng というモジュールは何者なのでしょうか?
2.Jinja2
Jinja2 はテンプレートエンジンで、テキストベースのファイルであればなんでも出力することができるのでHTMLに加え、CSVやXMLもレンダリングすることが出来ます。ただし、筆者はJinja2を使って実装したプロジェクトに出会ったことがなく、使用する機会は体感上少ないです。
・jinja2:Python 用のフル機能のテンプレート エンジン(https://baubaubau.hatenablog.com/entry/2020/10/29/202853)
3.Werkzeng
werkzeng は次の背景から開発されたWSGIユーティリティライブラリで、werkzengを用いていれば WSGIに準拠したアプリケーションを作ることができ、WebサーバとWebアプリケーションサーバを切り離した開発が可能になります。
・werkzeng:WSGI(ウィズギー)とは、PythonでWebアプリケーションとWebサーバーを接続する際に考案されたインターフェース定義。フレームワークごとに、サーバーと接続するためのインターフェースが異なっていたため、同一のアプリケーションであっても、接続できるサーバーが制限される(あるサーバーには接続できるのに、別のサーバーには接続できない)という事態が生じてしまったため、どのフレームワークでも同じように各種サーバーに接続できるようにしよう、ということで生まれたインターフェース定義がWSGI。Werkzeugは、そのWSGIを容易に扱えるようにしています。
Werkzeng が提供するもの
Werkzeugの公式サイト(https://werkzeug.palletsprojects.com/en/3.0.x/)をみると、Werkzeug を使用した場合、WSGI の基本的な「Hello World」アプリケーションは次のようになります。
Werkzeng を使用しないケース
def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
return ['Hello World!'.encode('utf-8')]
WSGI アプリケーションは、呼び出し可能なオブジェクトであり、呼び出される際、第一引数に環境辞書(environ)を第二引数にはstart_response(呼び出し可能オブジェクト)を渡すものであることが定義に含まれます。
Werkzeug を使用しない場合は、リクエストパラメータを取得・操作するために environ を直接操作する必要があり、レスポンスを作成するためには start_response を直接操作する必要があります。
Werkzeng を使用するケース
Werkzeug を使用した場合は、どちらも直接処理することがなく、提供された要求オブジェクトと応答オブジェクトを用いて適切に操作することができるようにします。つまり Werkzeug はリクエストおよびレスポンスを取得・作成を容易に実装するためのラッパーの役割を持ちます。
応答オブジェクト
Werkzeug を使用して直接処理せず、応答オブジェクトを使用した例を見てみましょう。
応答オブジェクトを使用してアプリケーションを作成する方法は次のとおりです。
from werkzeug.wrappers import Response
def application(environ, start_response):
response = Response('Hello World!', mimetype='text/plain')
return response(environ, start_response)
要求オブジェクト
要求オブジェクトを使用してクエリパラメータを編集するアプリケーション作成方法は次の通りです。
from werkzeug.wrappers import Request, Response
def application(environ, start_response):
request = Request(environ)
text = f"Hello {request.args.get('name', 'World')}!"
response = Response(text, mimetype='text/plain')
return response(environ, start_response)
Flaskは、この2つのライブラリだけをラップして作られていることから、追加モジュールがない状態では WSGI規格に準拠したHTTP通信、かつテンプレートエンジンを用いたレンダリングが可能なだけの軽量なフレームワークであることが理解できます。
Discussion