Spec-Zone.ru › Flask 3.0

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

Контекст приложения отслеживает данные на уровне приложения во время запроса, выполнения команды 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/3.0.x/appcontext/

Spec-Zone.ru

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