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

application contextは、リクエスト、CLIコマンド、もしくはその他の活動の期間中(訳注: 普通はWSGIサーバなどがリクエストを受信した後にWSGIレベルのアプリケーションであるFlaskアプリを起動した後、リクエストへの対応処理が終了してFlaskアプリを終了させるまでの間とほぼ同じ)、アプリケーションのレベルのデータを把握します(訳注: そのとき起動・リクエストへの対応をしているFlaskアプリのインスタンスに固有のデータの格納・操作を可能にする仕組みのような意味合い)。それぞれの関数でアプリケーションが渡されて回るよりも、プロキシのcurrent_appgが代わりにアクセスされます(訳注: 引数で受け取らなくてもFlaskアプリのインスタンスに関数内からアクセスできるように、flaskパッケージをimport後はflask.current_appやflask.gにアクセスすればそのとき実行中のFlaskアプリ固有のオブジェクトにアクセスできるようなことを指しています)。 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 the :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)の問題に陥りやすくなります(訳注: importするとFlaskアプリのインスタンスを作成して提供するモジュールやパッケージでは、そのパッケージの別モジュールなどのコードでimportすると、Flaskアプリのインスタンス内で同じFlaskアプリを作成してアクセスするような状況に陥りやすくなります)。app factoryパターンを使用したり、再利用可能なblueprintsまたはFlask拡張を書いたりするときは、importするためのappのインスタンスがそもそも存在しないでしょう(訳注: app factoryパターンのFlaskアプリのコードでは、importされただけではFlaskアプリのインスタンスを作成・提供せず、モジュールやパッケージ内で用意したfactory関数が呼び出されたときに初めてFlaskアプリのインスタンスを作成して返します。factory関数以外のコードでは、モジュールまたはパッケージをimportするだけでは(factory関数を呼び出さない限り)Flaskアプリのインスタンスを取得できなくなります。またblueprintやFlask拡張では、Flaskアプリのインスタンスを自分で作成はせず、既に作成済みのFlaskアプリのインスタンスに対して追加機能などを作成するため、基本的にblueprintやFlask拡張自身のコードでは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へアクセスします。 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():
    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.

werkzeug.local.LocalProxyを使用して、get_db()からcontext local(訳注: current_appと同じように、リクエストの期間中は、個々のリクエストで固有のオブジェクトのプロキシとして機能するもの、「リクエストのコンテキスト」のドキュメント参照)を新しく作成することが可能です 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.


もしFlask拡張を書いている場合は、gはユーザのコードのために予約しておく(使わないでおく)べきです。内部データをcontext自身に格納してもよいですが、十分に独自性のある名前を使うことを確実におさえてください。その時点のcontextは_app_ctx_stack.topを使ってアクセスされます。さらなる情報はFlask拡張の開発を確認してください。 If you're writing an extension, :data:`g` should be reserved for user code. You may store internal data on the context itself, but be sure to use a sufficiently unique name. The current context is accessed with :data:`_app_ctx_stack.top <_app_ctx_stack>`. For more information see :doc:`/extensiondev`.

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

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

もしsignals_availableがtrueのときは、次のsignalが送られます: appcontext_pushed, appcontext_tearing_down, そしてappcontext_poppedです。 If :data:`~signals.signals_available` is true, the following signals are sent: :data:`appcontext_pushed`, :data:`appcontext_tearing_down`, and :data:`appcontext_popped`.