アプリケーションファクトリ—フラスコのドキュメント

提供:Dev Guides
< FlaskFlask/docs/1.1.x/patterns/appfactories
移動先:案内検索

アプリケーションファクトリ

アプリケーションにパッケージとブループリント(ブループリントを使用したモジュラーアプリケーション)を既に使用している場合は、エクスペリエンスをさらに向上させるための非常に優れた方法がいくつかあります。 一般的なパターンは、ブループリントのインポート時にアプリケーションオブジェクトを作成することです。 ただし、このオブジェクトの作成を関数に移動すると、後でこのアプリの複数のインスタンスを作成できます。

では、なぜこれを実行したいのですか?

  1. テスト。 さまざまな設定でアプリケーションのインスタンスを作成して、すべてのケースをテストできます。
  2. 複数のインスタンス。 同じアプリケーションの異なるバージョンを実行したいとします。 もちろん、Webサーバーに異なる構成の複数のインスタンスを設定することもできますが、ファクトリを使用する場合は、同じアプリケーションプロセスで同じアプリケーションの複数のインスタンスを実行できるので便利です。

では、実際にそれをどのように実装しますか?

基本的な工場

アイデアは、関数でアプリケーションを設定することです。 このような:

def create_app(config_filename):
    app = Flask(__name__)
    app.config.from_pyfile(config_filename)

    from yourapplication.model import db
    db.init_app(app)

    from yourapplication.views.admin import admin
    from yourapplication.views.frontend import frontend
    app.register_blueprint(admin)
    app.register_blueprint(frontend)

    return app

欠点は、インポート時にブループリントでアプリケーションオブジェクトを使用できないことです。 ただし、リクエスト内から使用できます。 構成を使用してアプリケーションにアクセスするにはどうすればよいですか? current_app を使用します。

from flask import current_app, Blueprint, render_template
admin = Blueprint('admin', __name__, url_prefix='/admin')

@admin.route('/')
def index():
    return render_template(current_app.config['INDEX_TEMPLATE'])

ここでは、構成でテンプレートの名前を検索します。


工場と拡張機能

拡張機能オブジェクトが最初にアプリケーションにバインドされないように、拡張機能とアプリファクトリを作成することをお勧めします。

例として、 Flask-SQLAlchemy を使用して、これらの線に沿って何かを行うべきではありません。

def create_app(config_filename):
    app = Flask(__name__)
    app.config.from_pyfile(config_filename)

    db = SQLAlchemy(app)

しかし、むしろ、model.py(または同等のもの)では:

db = SQLAlchemy()

およびapplication.py(または同等のもの):

def create_app(config_filename):
    app = Flask(__name__)
    app.config.from_pyfile(config_filename)

    from yourapplication.model import db
    db.init_app(app)

このデザインパターンを使用すると、アプリケーション固有の状態が拡張オブジェクトに保存されないため、1つの拡張オブジェクトを複数のアプリに使用できます。 拡張機能の設計の詳細については、 Flask拡張機能の開発を参照してください。


アプリケーションの使用

このようなアプリケーションを実行するには、 Flask コマンドを使用できます。

$ export FLASK_APP=myapp
$ flask run

Flaskは、myapp内のファクトリ(create_appまたはmake_app)を自動的に検出します。 次のように、引数をファクトリに渡すこともできます。

$ export FLASK_APP="myapp:create_app('dev')"
$ flask run

次に、myappcreate_appファクトリが、文字列'dev'を引数として呼び出されます。 詳細については、コマンドラインインターフェイスを参照してください。


工場の改善

上記のファクトリ機能はあまり巧妙ではありませんが、改善することができます。 次の変更は簡単に実装できます。

  1. ファイルシステムに構成ファイルを作成する必要がないように、単体テストの構成値を渡すことができるようにします。
  2. アプリケーションのセットアップ時にブループリントから関数を呼び出して、アプリケーションの属性を変更する場所を確保します(要求ハンドラーの前後にフックするなど)。
  3. 必要に応じて、アプリケーションの作成時にWSGIミドルウェアを追加します。