Spec-Zone.ru › Flask 2.1

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

Контекст приложения отслеживает данные уровня приложения во время запроса, команды CLI или другой активности. Вместо передачи приложения каждой функции, вместо этого обращаются к прокси 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 имеет значение true, отправляются следующие сигналы: appcontext_pushed, appcontext_tearing_down и appcontext_popped.

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

Spec-Zone.ru

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