API de señales de Flask
Flask utiliza la librería Blinker para enviar señales cuando ocurren eventos clave. Puedes conectar estas señales para llevar a cabo registros adicionales, monitoreo, etc.
Las señales no son una funcionalidad central de Flask: la mayoría de los requisitos se pueden satisfacer mediante ganchos (como before_request, etc.).
Señales de solicitud principales
| Señal | Momento de activación | Parámetros transmitidos |
|---|---|---|
| request_started | Después de establecer el contexto de solicitud y antes del preprocesamiento | sender=app |
| request_finished | Una vez construida la respuesta y antes de enviarla | sender=app, response |
| got_request_exception | Cuando ocurre una excepción no manejada durante la solicitud | sender=app, exception |
| request_tearing_down | Cuando se destruye el contexto de solicitud (siempre se ejecuta) | sender=app, exc (opcional) |
Señales de contexto de aplicación
| Señal | Momento de activación | Parámetros transmitidos |
|---|---|---|
| appcontext_pushed | Cuando se empuja el contexto de aplicación a la pila | sender=app |
| appcontext_popped | Cuando se saca el contexto de aplicación de la pila | sender=app |
| appcontext_tearing_down | Cuando se destruye el contexto de aplicación (siempre se ejecuta) | sender=app, exc (opcional) |
Señales de plantillas y mensajes
| Señal | Momento de activación | Parámetros transmitidos |
|---|---|---|
| template_rendered | Cuando el renderizado de la plantilla es exitoso | sender=app, template, context |
| before_render_template | Antes de renderizar la plantilla | sender=app, template, context |
| message_flashed | Cuando se llama a flash() | sender=app, message, category |
Formas de conectar señales
| Forma | Descripción |
|---|---|
| signal.connect(func, app) | Conecta la señal directamente. func recibe el sender y argumentos de palabra clave. |
| signal.connect_via(app)(func) | Forma de decorador. Automáticamente usa app como sender. |
| with signal.connected_to(func, app): | Administrador de contexto. Conecta la señal temporalmente. |
Código de ejemplo
Ejemplo
from flask import Flask, request_started, request_finished, template_rendered
app = Flask(__name__)
# Método 1: conexión directa
def log_request_start(sender, **extra):
print(f"Request started on {sender.name}")
request_started.connect(log_request_start, app)
# Método 2: conexión por decorador
@request_finished.connect_via(app)
def log_request_end(sender, response, **extra):
print(f"Request finished with status {response.status_code}")
# Método 3: señal de renderizado de plantilla
@template_rendered.connect_via(app)
def log_template(sender, template, context, **extra):
print(f"Template rendered: {template.name}")
# Método 4: capturar excepciones
from flask import got_request_exception
def log_error(sender, exception, **extra):
sender.logger.error(f"Exception: {exception}")
got_request_exception.connect(log_error, app)
app = Flask(__name__)
# Método 1: conexión directa
def log_request_start(sender, **extra):
print(f"Request started on {sender.name}")
request_started.connect(log_request_start, app)
# Método 2: conexión por decorador
@request_finished.connect_via(app)
def log_request_end(sender, response, **extra):
print(f"Request finished with status {response.status_code}")
# Método 3: señal de renderizado de plantilla
@template_rendered.connect_via(app)
def log_template(sender, template, context, **extra):
print(f"Template rendered: {template.name}")
# Método 4: capturar excepciones
from flask import got_request_exception
def log_error(sender, exception, **extra):
sender.logger.error(f"Exception: {exception}")
got_request_exception.connect(log_error, app)