アプリケーションのコンテキスト(The Application Context) The Application Context

application contextは、リクエスト、CLIコマンド、もしくはその他の活動の期間中(訳注: 普通はWSGIサーバなどがリクエストを受信後、WSGIレベルのアプリケーションであるFlaskアプリを起動してから、リクエストへの対応処理が終了してFlaskアプリをWSGIサーバなどが終了させるまでの間とほぼ同じ)、アプリケーションのレベルのデータを把握します(訳注: 他のリクエストに対応中のFlaskアプリのインスタンスとは独立して、そのとき起動しリクエストへの対応をしているFlaskアプリのインスタンスに固有のデータの格納・操作を可能にする仕組みのような意味合い)。それぞれの関数へアプリケーションが渡されて回るよりも、プロキシのcurrent_appgが代わりにアクセスされます(訳注: 引数で受け取らなくてもFlaskアプリのインスタンスに関数内からアクセスできるように、import flaskのようにFlaskパッケージをimportすれば、例えば同時に来た2つのリクエストを処理しているFlaskアプリAとBがあったとき、関数内部からflask.current_appflask.gにAとBが同時にアクセスした場合でも、AとBそれぞれで固有のオブジェクトにアクセスできるようなことを指しています)。 The application context keeps track of the application-level data during a request, CLI command, or other activity. Rather than passing the application around to each function, the :data:`current_app` and :data:`g` proxies are accessed instead.

これは、リクエストに対応中はリクエストのレベルのデータを把握するリクエストのコンテキスト(The Request Context)と似ています。request contextがpushされたとき、対応するapplication contextもpushされます(訳注: application contextとrequest contextで保持するデータはFlask内でスタックのデータ構造を使って管理されており、一般的にスタックへデータを追加することをpushといいます)。 This is similar to :doc:`/reqcontext`, which keeps track of request-level data during a request. A corresponding application context is pushed when a request context is pushed.

コンテキストの目的(Purpose of the Context) Purpose of the Context

Flaskアプリケーションのオブジェクトには、configのように、viewやCLIのコマンドの中からアクセスするときに便利な属性があります。しかしながら、appのインスタンスを自分のプロジェクトのモジュール内でimportすると、循環import(circular import)の問題に陥りやすくなります(訳注: 2つのモジュールがお互い依存し合うとき循環importになります。参考までに、パッケージ分割の説明で循環importが例と一緒に説明されています)。app factoryパターンを使用するときや、再利用可能なblueprintsまたはFlask拡張を書くときには、importするためのappのインスタンスがそもそも存在しないでしょう(訳注: app factoryパターンのFlaskアプリのモジュールやパッケージでは、基本的にモジュールレベルの変数でFlaskアプリのインスタンスを作成・格納せず、factory関数が呼び出されたときに初めてFlaskアプリのインスタンスを作成して返します。factory関数以外のコードでは、関数の引数として受け取らずにFlaskインスタンスに直接アクセスすることは基本的にできません。またblueprintやFlask拡張は、Flaskアプリの開発者がFlaskのインスタンスに追加したい機能などを提供します。通常blueprintなどはFlaskインスタンス自体の作成やimportはしない前提で作成する必要があり、コード内では関数の引数で受け取る以外にFlaskインスタンスに直接アクセスすることは基本的にできません)。 The :class:`Flask` application object has attributes, such as :attr:`~Flask.config`, that are useful to access within views and :doc:`CLI commands </cli>`. However, importing the ``app`` instance within the modules in your project is prone to circular import issues. When using the :doc:`app factory pattern </patterns/appfactories>` or writing reusable :doc:`blueprints </blueprints>` or :doc:`extensions </extensions>` there won't be an ``app`` instance to import at all.

Flaskはこの問題を、application contextを使って解決します。app(Flaskアプリのインスタンス)を直接参照するのではなく、その時点の活動を処理しているアプリケーションを指すプロキシになるcurrent_appを使用できます。 Flask solves this issue with the *application context*. Rather than referring to an ``app`` directly, you use the :data:`current_app` proxy, which points to the application handling the current activity.

リクエストを処理するとき、Flaskは自動的にapplication contextをpushします。リクエストの期間中に実行するview関数、エラー処理、およびその他の関数は、current_app(application contextのproxy)へアクセスできます。 Flask automatically *pushes* an application context when handling a request. View functions, error handlers, and other functions that run during a request will have access to :data:`current_app`.

Flaskは@app.cli.command()を使用してFlask.cliに登録されたCLIコマンドを実行するときも、自動的にapp contextをpushします。 Flask will also automatically push an app context when running CLI commands registered with :attr:`Flask.cli` using ``@app.cli.command()``.

コンテキストの生存期間(Lifetime of the Context) Lifetime of the Context

application contextは必要に応じて作成され破壊されます。Flaskアプリケーションがリクエストの処理を始めたとき、Flaskアプリケーションはapplication contextとrequest contextをpushします。リクエストが終了するとき、Flaskアプリケーションはrequest contextをpopし(訳注: 一般的にスタックからデータを取り出すことをpopといいます)、それからapplication contextをpopします。典型的には、application contextはリクエストと同じ生存期間を持ちます。 The application context is created and destroyed as necessary. When a Flask application begins handling a request, it pushes an application context and a :doc:`request context </reqcontext>`. When the request ends it pops the request context then the application context. Typically, an application context will have the same lifetime as a request.

contextがどのように機能するかとリクエストの全体ライフサイクル(訳注: 作成されてから消滅するまで)に関するさらなる情報は、リクエストのコンテキスト(The Request Context)を確認してください。 See :doc:`/reqcontext` for more information about how the contexts work and the full life cycle of a request.

手作業でのコンテキストの登録(Manually Push a Context) Manually Push a Context

もしcurrent_appまたはcurrent_appを使うものへのアクセスを試すとき、application contextの外側の場合(application contextがスタックへpushされた状態でない場合)、以下のようなエラーメッセージを得るでしょう: If you try to access :data:`current_app`, or anything that uses it, outside an application context, you'll get this error message:

RuntimeError: Working outside of application context.

This typically means that you attempted to use functionality that
needed to interface with the current application object in some way.
To solve this, set up an application context with app.app_context().

もし自分のアプリケーションを設定中に、例えばFlask拡張を初期化しているときなどに、このエラーを見た場合は、appへの直接アクセスが可能なので(訳注: app設定中であれば、appインスタンスに直接アクセスして設定の初期化や値の定義などができる状況なはずなので)contextを手動でpushすることが可能です。withブロックの中でapp_context()を使用すると、ブロックの内側で実行しているものは全てcurrent_appへアクセスできるようになります。: If you see that error while configuring your application, such as when initializing an extension, you can push a context manually since you have direct access to the ``app``. Use :meth:`~Flask.app_context` in a ``with`` block, and everything that runs in the block will have access to :data:`current_app`. ::

def create_app():
    app = Flask(__name__)

    with app.app_context():
        init_db()

    return app

もしアプリケーションの設定処理と関係のない、どこか別の場所のコードでこのエラーを見た場合は、そのコードをview関数またはCLIコマンドへ移動するべきだと示している可能性が最も高いです。 If you see that error somewhere else in your code not related to configuring the application, it most likely indicates that you should move that code into a view function or CLI command.

データの格納 Storing Data

application contextは、リクエストまたはCLIコマンドの期間中に、共通のデータを格納するにはよい場所です。Flaskはその目的のためにgオブジェクトを提供します。それはシンプルな名前空間オブジェクトで、application contextと同じ生存期間を持ちます。 The application context is a good place to store common data during a request or CLI command. Flask provides the :data:`g object <g>` for this purpose. It is a simple namespace object that has the same lifetime as an application context.

注釈

名前のgは「global」の略称ですが、それはcontextの中でグローバルなデータであることを指しています。gにあるデータはcontextが終了すると消失し、それは(複数の)リクエストの間でのデータを格納するには適切な場所ではありません。(複数の)リクエストをまたいでデータを格納するには、sessionまたはデータベースを使用してください。 The ``g`` name stands for "global", but that is referring to the data being global *within a context*. The data on ``g`` is lost after the context ends, and it is not an appropriate place to store data between requests. Use the :data:`session` or a database to store data across requests.

gのよくある利用方法はリクエストの処理中にリソースを管理することです。 A common use for :data:`g` is to manage resources during a request.

  1. get_X()で、リソースXが存在しない場合にはそれを作成し、g.Xとしてキャッシュします。 ``get_X()`` creates resource ``X`` if it does not exist, caching it as ``g.X``.

  2. teardown_X()で、リソースがもし存在する場合には(訳注: ファイルやネットワーク接続などでは)それを閉じるか、もしくは(訳注: メモリなどでは)割り当てを解消します。その処理はteardown_appcontext()のハンドラとして(appに)登録されます。 ``teardown_X()`` closes or otherwise deallocates the resource if it exists. It is registered as a :meth:`~Flask.teardown_appcontext` handler.

例えば、データベースの接続(connection)を以下のようなパターンを使って管理できます: For example, you can manage a database connection using this pattern::

from flask import g

def get_db():
    if 'db' not in g:
        g.db = connect_to_database()

    return g.db

@app.teardown_appcontext
def teardown_db(exception):
    db = g.pop('db', None)

    if db is not None:
        db.close()

リクエストの処理中、get_db()への全ての呼び出しは同じconnectionを返すようになり、リクエストが終わるときには、そのconnectionは自動的に閉じられるようになります。 During a request, every call to ``get_db()`` will return the same connection, and it will be closed automatically at the end of the request.

get_db()からcontextに局所的なもの(訳注: current_appと同じように、リクエストの期間中は、個々のリクエストで固有のオブジェクトへアクセスできるようにするプロキシとして機能するもの、「リクエストのコンテキスト(The Request Context)」のドキュメント参照)を新しく作成するために、werkzeug.local.LocalProxyを使用できます: You can use :class:`~werkzeug.local.LocalProxy` to make a new context local from ``get_db()``::

from werkzeug.local import LocalProxy
db = LocalProxy(get_db)

current_appが機能するのと同じやり方で、(この例では)dbへのアクセスは内部でget_dbを呼び出すようになります。 Accessing ``db`` will call ``get_db`` internally, in the same way that :data:`current_app` works.

出来事と合図(Events and Signals) Events and Signals

アプリケーションは、application contextが取り出された(pop)とき、teardown_appcontext()に登録された関数を呼び出します。 The application will call functions registered with :meth:`~Flask.teardown_appcontext` when the application context is popped.

もしsignals_availableがtrueのときは、次のsignalが送られます: appcontext_pushedappcontext_tearing_down、そしてappcontext_poppedです(訳注: ここで紹介されたシグナルがblinkerで実装されており、使えるようになります)。 If :data:`~signals.signals_available` is true, the following signals are sent: :data:`appcontext_pushed`, :data:`appcontext_tearing_down`, and :data:`appcontext_popped`.