Spec-Zone.ru › Flask

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

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

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

Назначение контекста

Объект приложения Flask имеет атрибуты, такие как config, которые полезны для доступа внутри представлений и команд CLI. Однако импорт экземпляра app в модули вашего проекта может привести к проблемам с циклическими импортами. При использовании шаблона фабрики приложения или написании многократно используемых blueprint или расширений, экземпляра 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.

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

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

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

© 2010 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/stable/appcontext/

Spec-Zone.ru

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