Spec-Zone.ru › Flask 2.0

Контекст приложения

Контекст приложения отслеживает данные уровня приложения во время запроса, командной строки или другой активности. Вместо передачи приложения каждой функции, вместо этого обращаются к прокси current_app и g.

Это аналогично Контексту запроса, который отслеживает данные уровня запроса во время запроса. Соответствующий контекст приложения подталкивается, когда подталкивается контекст запроса.

Цель контекста

Объект приложения Flask имеет атрибуты, такие как config, которые полезны для доступа внутри представлений и команд CLI. Однако импортирование экземпляра app в модули вашего проекта может привести к проблемам с циклическим импортом. При использовании шаблона фабрики приложений или написании многократно используемых blueprints или расширений экземпляра app для импорта вообще не будет.

Flask решает эту проблему с помощью контекста приложения. Вместо того, чтобы ссылаться на app напрямую, вы используете прокси current_app, который указывает на приложение, обрабатывающее текущую активность.

Flask автоматически подталкивает контекст приложения при обработке запроса. Функции представлений, обработчики ошибок и другие функции, выполняющиеся во время запроса, будут иметь доступ к current_app.

Flask также автоматически подтолкнет контекст приложения при выполнении команд CLI, зарегистрированных с Flask.cli с помощью @app.cli.command().

Срок действия контекста

Контекст приложения создается и уничтожается по мере необходимости. Когда приложение Flask начинает обрабатывать запрос, оно подталкивает контекст приложения и контекст запроса. По окончании запроса контекст запроса удаляется, затем контекст приложения. Как правило, контекст приложения имеет такой же срок действия, как и запрос.

Дополнительную информацию о работе контекстов и полном жизненном цикле запроса см. в разделе Контекст запроса.

Вручную подтолкнуть контекст

Если вы попытаетесь получить доступ к current_app или чему-либо, использующему его, вне контекста приложения, вы получите это сообщение об ошибке:

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().

Если вы видите эту ошибку при настройке приложения, например, при инициализации расширения, вы можете вручную подтолкнуть контекст, поскольку у вас есть прямой доступ к app. Используйте app_context() в блоке with, и все, что выполняется в этом блоке, будет иметь доступ к current_app.

def create_app():
    app = Flask(__name__)

    with app.app_context():
        init_db()

    return app

Если вы видите эту ошибку где-то еще в вашем коде, не связанном с настройкой приложения, скорее всего, это означает, что этот код необходимо переместить в функцию представления или команду CLI.

Хранение данных

Контекст приложения — хорошее место для хранения общих данных во время запроса или команды CLI. Flask предоставляет g object для этой цели. Это простой объект пространства имен, который имеет такой же срок действия, как и контекст приложения.

Примечание

Имя g означает «глобальный», но это относится к данным, которые являются глобальными внутри контекста. Данные в g теряются после завершения контекста, и это не подходящее место для хранения данных между запросами. Используйте session или базу данных для хранения данных между запросами.

Типичное применение g — управление ресурсами во время запроса.

  1. get_X() создает ресурс X, если он не существует, кэшируя его как g.X.
  2. teardown_X() закрывает или иным образом освобождает ресурс, если он существует. Он зарегистрирован как обработчик teardown_appcontext().

Например, вы можете управлять подключением к базе данных с помощью этого шаблона:

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() вернет одно и то же подключение, и оно будет закрыто автоматически в конце запроса.

Вы можете использовать LocalProxy для создания нового контекстного локального из get_db():

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

Доступ к db вызовет get_db внутри, точно так же, как работает current_app.

Если вы пишете расширение, g следует сохранять для кода пользователя. Вы можете хранить внутренние данные в самом контексте, но обязательно используйте достаточно уникальное имя. Текущий контекст доступен с помощью _app_ctx_stack.top. Дополнительную информацию см. в Разработка расширений Flask.

События и сигналы

Приложение будет вызывать функции, зарегистрированные с помощью teardown_appcontext(), когда контекст приложения удаляется.

Если signals_available истинно, отправляются следующие сигналы: appcontext_pushed, appcontext_tearing_down и appcontext_popped.

© 2007–2021 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/2.0.x/appcontext/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API