Сообщить об ошибке.

Глобальный объект flask.g в приложении Flask Python

Передача значений от одной функции к другой во Flask

Для обмена данными, допустимыми только для одного запроса, от одной функции к другой, глобальная переменная Python недостаточно хороша, т.к. в многопоточных средах может возникнуть условия гонки за эту переменную. Фреймворк Flask предоставляет специальный объект пространства имен flask.g, который может хранить данные в контексте приложения.

Глобальный объект пространства имен flask.g гарантирует, что он действителен только для активного запроса и будет возвращать разные значения для каждого запроса. В двух словах: flask.g предназначен для передачи значений переменных от одной функции к другой в рамках одного запроса к сайту. Он делает ожидаемые вещи, как и для запроса и сессии/сеанса.

На самом деле, объект пространства имен flask.g, представляет собой прокси объект для класса app.app_ctx_globals_class экземпляра приложения, который по умолчанию имеет значение flask.ctx._AppCtxGlobals.

В общем это хорошее место для хранения ресурсов во время запроса конкретного запроса. Очень распространенным шаблоном является хранение информации об авторизации пользователя и подключениях к базе данных в контексте приложения или в объекте flask.g. Общий шаблон для этого состоит в том, чтобы поместить объект туда в начале запроса, а затем удалить его в конце запроса. Представьте, например, этот код, чтобы получить текущего пользователя:

def get_user():
    user = getattr(g, 'user', None)
    if user is None:
        user = fetch_current_user_from_database()
        g.user = user
    return user

Внутри шаблонов приложения Flask, также есть доступ к глобальному объекту flask.g

Класс flask.ctx._AppCtxGlobals.

Класс flask.ctx._AppCtxGlobals - это простой объект. Предназначен для использования в качестве пространства имен для хранения данных в контексте приложения.

Создание контекста приложения, автоматически создает этот объект, который, в свою очередь, становится доступным в качестве глобального прокси-объекта flask.g.

Операции, поддерживающие flask.ctx._AppCtxGlobals.

Так, как глобальный объект flask.g - это прокси для flask.ctx._AppCtxGlobals, то следовательно он так же поддерживает все описанные ниже операции.

  • 'key' in g: проверяет, присутствует ли атрибут 'key' в глобальном объекте flask.g.
  • iter(g): возвращает итератор по именам атрибутов глобального объекта flask.g.
  • g.get(name, default=None): получает атрибут по имени name или если name отсутствует возвращает значение по умолчанию default. Другими словами, ведет себя подобно dict.get().
  • g.pop(name, default=<object object>): возвращает, а потом удаляет атрибут по имени name или если name отсутствует возвращает значение по умолчанию default. Другими словами, ведет себя подобно dict.pop().
  • g.setdefault(name, default=None): получает значение атрибута name, если оно присутствует, если отсутствует, то устанавливает атрибут name и возвращает значение по умолчанию default. Другими словами, ведет себя подобно dict.setdefault().

Пример использования глобального объекта flask.g.

Простой пример того, как можно хранить подключение к базе данных в глобальном объекте flask.g в рамках одного запроса, на примере использования базы данных SQLite 3 в приложении Flask:

import sqlite3
from flask import g

# расположение файла БД SQLite 3
DATABASE = '/path/to/database.db'

def get_db():
    """ Возвращает объект соединения с БД"""
    db = getattr(g, '_database', None)
    if db is None:
        db = g._database = sqlite3.connect(DATABASE)
    return db

@app.teardown_appcontext
def close_connection(exception):
    """Закрывает соединение с с БД"""
    db = getattr(g, '_database', None)
    if db is not None:
        db.close()

А затем использовать get_db() в функциях-представлениях.

@app.route('/')
def index():
    cur = get_db().cursor()
    ...