Flask Signals API
Flask uses the Blinker library to send signals when key events occur. You can connect to these signals to perform additional logging, monitoring, and other operations.
Signals are not a core feature of Flask—most needs can be met through hooks (such as before_request).
Core request signals
| signal | Trigger timing | Passed Parameters |
|---|---|---|
| request_started | After the request context is established, before preprocessing | sender=app |
| request_finished | After the response is fully constructed, before sending | sender=app, response |
| got_request_exception | An unhandled exception occurs during the request | sender=app, exception |
| request_tearing_down | When the request context is destroyed (always executed) | sender=app, exc (optional) |
Application context signals
| signal | Trigger timing | Passed Parameters |
|---|---|---|
| appcontext_pushed | When the application context is pushed onto the stack | sender=app |
| appcontext_popped | When the application context is popped from the stack | sender=app |
| appcontext_tearing_down | When the application context is destroyed (always executed) | sender=app, exc (optional) |
Template and message signals
| signal | Trigger timing | Passed Parameters |
|---|---|---|
| template_rendered | When template rendering succeeds | sender=app, template, context |
| before_render_template | Before template rendering | sender=app, template, context |
| message_flashed | When calling flash() | sender=app, message, category |
Ways to connect signals
| Method | Description |
|---|---|
| signal.connect(func, app) | Connect signals directly. func receives sender and keyword arguments. |
| signal.connect_via(app)(func) | Decorator form. Automatically uses app as sender. |
| with signal.connected_to(func, app): | Context manager. Temporary connection signal |
Code Examples
Example
from flask import Flask, request_started, request_finished, template_rendered
app = Flask(__name__)
# Method 1: Direct Connection
def log_request_start(sender, **extra):
print(f"Request started on {sender.name}")
request_started.connect(log_request_start, app)
# Method 2: Decorator Connection
@request_finished.connect_via(app)
def log_request_end(sender, response, **extra):
print(f"Request finished with status {response.status_code}")
# Method 3: Template Rendering Signal
@template_rendered.connect_via(app)
def log_template(sender, template, context, **extra):
print(f"Template rendered: {template.name}")
# Method 4: Catch Exceptions
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__)
# Method 1: Direct Connection
def log_request_start(sender, **extra):
print(f"Request started on {sender.name}")
request_started.connect(log_request_start, app)
# Method 2: Decorator Connection
@request_finished.connect_via(app)
def log_request_end(sender, response, **extra):
print(f"Request finished with status {response.status_code}")
# Method 3: Template Rendering Signal
@template_rendered.connect_via(app)
def log_template(sender, template, context, **extra):
print(f"Template rendered: {template.name}")
# Method 4: Catch Exceptions
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)