Spec-Zone.ru › Flask 2.3

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

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

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

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

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

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

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

Flask также автоматически подталкивает контекст приложения при выполнении команд командной строки, зарегистрированных с 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

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

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

Контекст приложения — хорошее место для хранения общих данных во время запроса или выполнения команды из командной строки. 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.

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

Spec-Zone.ru

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