El contexto de la aplicación

El contexto de la aplicación mantiene un seguimiento de los datos a nivel de aplicación durante una solicitud, comando CLI u otra actividad. En lugar de pasar la aplicación a cada función, se accede a los proxies current_app y g.

Esto es similar a El contexto de la solicitud, que mantiene un seguimiento de los datos a nivel de solicitud durante una petición. Un contexto de aplicación correspondiente se empuja cuando se empuja un contexto de solicitud.

Propósito del contexto

El objeto de aplicación Flask tiene atributos, como config, que son útiles para acceder dentro de las vistas y los comandos CLI. Sin embargo, la importación de la instancia app dentro de los módulos de tu proyecto es propensa a problemas de importación circular. Cuando se utiliza el patrón app factory o se escriben blueprints o extensions no habrá ninguna instancia de app para importar.

Flask resuelve este problema con el contexto de aplicación. En lugar de referirse a una app directamente, se utiliza el proxy current_app, que apunta a la aplicación que maneja la actividad actual.

Flask automáticamente empuja un contexto de aplicación cuando maneja una solicitud. Las funciones de vista, los manejadores de errores y otras funciones que se ejecutan durante una solicitud tendrán acceso a current_app.

Flask también empujará automáticamente un contexto de aplicación cuando ejecute comandos CLI registrados con Flask.cli usando @app.cli.command().

La duración del contexto

El contexto de aplicación se crea y destruye según sea necesario. Cuando una aplicación Flask comienza a manejar una solicitud, empuja un contexto de aplicación y un contexto de solicitud. Cuando la petición finaliza, el contexto de petición y el contexto de aplicación desaparecen. Normalmente, un contexto de aplicación tendrá el mismo tiempo de vida que una petición.

Consulte El contexto de la solicitud para obtener más información sobre el funcionamiento de los contextos y el ciclo de vida completo de una solicitud.

Empujar manualmente un contexto

Si intentas acceder a current_app, o a cualquier cosa que lo utilice, fuera de un contexto de aplicación, obtendrás este mensaje de error:

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().

Si ves ese error mientras configuras tu aplicación, como por ejemplo al inicializar una extensión, puedes empujar un contexto manualmente ya que tienes acceso directo a la app. Usa app_context() en un bloque with, y todo lo que se ejecute en el bloque tendrá acceso a current_app.

def create_app():
    app = Flask(__name__)

    with app.app_context():
        init_db()

    return app

Si ves ese error en algún otro lugar de tu código no relacionado con la configuración de la aplicación, lo más probable es que indique que debes mover ese código a una función de la vista o a un comando CLI.

Almacenamiento de datos

El contexto de la aplicación es un buen lugar para almacenar datos comunes durante una solicitud o un comando CLI. Flask proporciona el objeto g para este propósito. Es un simple objeto de espacio de nombres que tiene el mismo tiempo de vida que un contexto de aplicación.

Nota

El nombre g significa «global», pero eso se refiere a que los datos son globales dentro de un contexto. Los datos en g se pierden cuando el contexto termina, y no es un lugar apropiado para almacenar datos entre peticiones. Utiliza session o una base de datos para almacenar datos entre peticiones.

Un uso común de g es gestionar los recursos durante una solicitud.

  1. get_X() crea el recurso X si no existe, almacenándolo en caché como g.X.

  2. teardown_X() cierra o desasigna el recurso si existe. Se registra como un manejador teardown_appcontext().

Por ejemplo, puede gestionar una conexión de base de datos utilizando este patrón:

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()

Durante una petición, cada llamada a get_db() devolverá la misma conexión, y se cerrará automáticamente al final de la petición.

Puede utilizar LocalProxy para hacer un nuevo contexto local de get_db():

from werkzeug.local import LocalProxy
db = LocalProxy(get_db)

Al acceder a db se llamará internamente a get_db, del mismo modo que funciona current_app.

Eventos y señales

La aplicación llamará a las funciones registradas con teardown_appcontext() cuando el contexto de la aplicación sea expulsado.

The following signals are sent: appcontext_pushed, appcontext_tearing_down, and appcontext_popped.