アプリケーションファクトリ、アプリケーションの工場かな??
flaskでWebアプリを作成するときの作法のようなものだね。
flaskの「チュートリアル」でflaskrという小さなブログアプリを作成するチュートリアルを行っています。アプリケーションファクトリという考え方でflaskでのWebアプリを作成すると良いそうです。
flaskのチュートリアルはこちらです。「Application Setup」の項目です。
こんな人の役に立つかも
・Flaskを勉強したい人
・PythonでWebアプリケーション作成をしたい人
・flaskrチュートリアルを行っている人
Flaskアプリケーションのセットアップ
flaskでは、Webアプリケーションをひとつのインスタンスとして作成します。そのため、flaskのアプリはすべてFlaskクラスのインスタンスになります。このインスタンスの作成方法がアプリケーションファクトリという機能(方法?)を使うことで、開発規模が拡大したときなどに柔軟に対応できるようになるようです。
今までのチュートリアル(クイックスタート)では
app = Flask(__name__)
のように、「application.py」というViewのプログラムにFlaskのインスタンスを作成してルーティングを行ってきました。
このように、プログラムの最初でインスタンスを作成する方法(「グローバルインスタンス」を作成するやり方)はシンプルで便利ですが、プロジェクトが成長していくと、やりにくくなっていくそうです。
そこで、関数内でFlaskアプリのインスタンスを作成するような方法が採用されます。このflaskアプリのインスタンスを返す関数(機能)を「アプリケーションファクトリ」と言います。
プログラムを作成して、アプリケーションファクトリでflaskアプリのインスタンスを作成する方法を見ていきます。
すごく教科書的な文体になってしまいました。
チュートリアルプログラムの実装
実装を行う際に、前回作成した「flask-tutrial」フォルダへ移動します。
cd flask-tutrial
次に、前回のアプリケーションの構成でみたように、WebアプリケーションのPythonプログラムを格納するための「flaskr」フォルダを作成します。
mkdir flaskr
flaskrフォルダに次の「__init__.py」を作成します。以下のようなファイル構成になりました。
「__init__.py」は以下のような内容でコーディングを行なっておきます。
import os
from flask import Flask
#アプリケーションファクトリの機能を果たす関数「create_app」
def create_app(test_config=None):
#Flaskクラスからappインスタンスを作成します。相対パスをTrueに。
app = Flask(__name__, instance_relative_config=True)
#ここでappインスタンスにシークレットキーを設定。また、データベースファイルの場所を指定。
#もちろん本番アプリではシークレットキーはランダムな文字列を生成して利用。
app.config.from_mapping(
SECRET_KEY='dev',
DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),
)
if test_config is None:
app.config.from_pyfile('config.py', silent=True)
else:
app.config.from_mapping(test_config)
#エラー処理
#データベースのファイルをapp.instance_pathに作成するので、この階層が作成されなかった場合エラー
try:
os.makedirs(app.instance_path)
except OSError:
pass
#URL「/hello」にアクセスすることでインスタンスが動作しているか確認用です。
@app.route('/hello')
def hello():
return 'Hello, World!'
#appインスタンスを返す
return app
プログラムの詳細については、コメントアウトで追記させていただきました。
test_configという条件がまだよくわかっていませんが、プログラムのテストの時と本番の時にWebアプリの設定を変化させるような形だと考えています。
Pythonの「__init__.py」について
唐突に「__init__.py」のお話になってしまいました^^;
「__init__.py」はPythonのパッケージで初期化を行うときに利用されます。(パッケージについては今回は詳しく触れませんが、Pythonのパッケージは、numpyやpandasといったimportするプログラムのかたまりです。)
今回作成するflaskrアプリでも「__init__.py」がflaskrフォルダの中に「__init__.py」が存在しているので、パッケージの構成となっていることがわかります。
この「__init__.py」で、flaskrディレクトリをPythonパッケージとして扱うことができるようになります。
「__init__.py」を導入した構成で、より柔軟に拡張できそうな感じがしてきました。
この形を覚えておきたいですね。
アプリを動作させる
「__init__.py」のみから構成されるWebアプリケーションを動作させてみます。
まずは、現在「flask-tutrial」にいると思いますので、そこでPythonの仮想環境を起動させます。
mac
$. venv/bin/activate
windows
> venv/Scripts/activate
仮想環境が起動したら、次のように環境変数を設定します。
今までは、FLASK_APPが「application.py」のように特定のPythonプログラムファイルであったのに対して「flaskr」とフォルダ指定になっている点です。
macの場合
(venv)$ export FLASK_APP=flaskr
(venv)$ export FLASK_ENV=development
(venv)$ flask run
windowsの場合
(venv)> set FLASK_APP=flaskr
(venv)> set FLASK_ENV=development
(venv)> flask run
これで、デバッグ用のWebサーバーが起動しましたので、次にブラウザから「localhost:5000/hello」へアクセスしてみます。
無事、「__init__.py」が動作していることを確認することができました。
まだよくわかっていない点
「flask run」コマンドを実行することで「__init__.py」の処理が流れるのはわかったのですが、関数である「create_app」が実行されている点がよくわかっていません^^;
実際、動作確認のときに「/hello」にアクセスしてルーティングされているので、ここで実装しているappインスタンスが動作しているのですが。
とりあえず、このように「アプリケーションファクトリ」というものを定義することでappのインスタンスの設定などを行うことができる、と理解しています。