How to Set Up Alerts and Scheduled Reports in Apache Superset: Email, Slack, and Webhook Configuration
Apache Superset enables automated alerts and scheduled reports through Celery workers that evaluate SQL thresholds or capture dashboard snapshots and dispatch notifications via the EmailNotification, SlackNotification, or WebhookNotification classes.
Setting up alerts and scheduled reports in Apache Superset requires configuring the underlying notification infrastructure and defining ReportSchedule objects that specify when and where to send data. This guide covers the complete implementation path from feature flags to production deployment, referencing the actual source code in the apache/superset repository.
Core Architecture and Data Models
All scheduling logic resides in superset/reports/models.py. The ReportSchedule ORM class stores the crontab expression, SQL query (for alerts), and references to charts or dashboards. Recipients are modeled separately through the ReportRecipient class, which uses the ReportRecipientType enumeration to distinguish channels:
class ReportRecipientType(StrEnum):
EMAIL = "Email"
SLACK = "Slack"
SLACKV2 = "SlackV2"
WEBHOOK = "Webhook"
# source: superset/reports/models.py#L65-L70
Each recipient record stores a JSON recipient_config_json field containing the target address, channel name, or webhook URL.
Alert Evaluation Logic
For threshold-based alerts, Superset executes the AlertCommand class defined in superset/commands/report/alert.py. The run() method evaluates the SQL query and applies a validator—either NOT_NULL or OPERATOR—to determine if the alert triggers:
if self._is_validator_not_null:
self._report_schedule.last_value_row_json = str(self._result)
is_null_or_nan = self._result is None or pd.isna(self._result)
triggered = bool(self._result != 0 and not is_null_or_nan)
else:
# operator validator
triggered = OPERATOR_FUNCTIONS[operator](self._result, threshold)
# source: superset/commands/report/alert.py#L83-L95
When triggered is True, the execution pipeline proceeds to the notification phase.
Notification Channel Configuration
Superset dispatches messages through three primary notification classes located in superset/reports/notifications/. Each requires specific backend configuration.
Email Notifications
The EmailNotification class in superset/reports/notifications/email.py constructs HTML emails with optional CSV or PDF attachments. It relies on the SMTP helper send_email_smtp from superset/utils/core.py.
Required configuration in superset_config.py:
SMTP_HOST = "smtp.example.com"
SMTP_PORT = 587
SMTP_USER = "[email protected]"
SMTP_PASSWORD = "your_secure_password"
MAIL_DEFAULT_SENDER = "[email protected]"
EMAIL_REPORTS_SUBJECT_PREFIX = "[Superset Report]" # default defined in superset/config.py#L1976
The subject line is generated dynamically:
def _get_subject(self) -> str:
return __(
"%(prefix)s %(title)s",
prefix=current_app.config["EMAIL_REPORTS_SUBJECT_PREFIX"],
title=self._name,
)
# source: superset/reports/notifications/email.py#L204-L208
Slack Notifications
The SlackNotification class in superset/reports/notifications/slack.py supports the legacy Slack Web API. It uploads files or posts messages using the Slack SDK client retrieved from superset/utils/slack.py.
Configuration in superset_config.py:
SLACK_API_TOKEN = "xoxb-your-bot-token"
The token requires chat:write and files:write scopes. The notification logic handles file uploads versus simple messages:
client = get_slack_client()
channel = self._get_channel()
if files:
client.files_upload(..., filetype=file_type)
else:
client.chat_postMessage(channel=channel, text=body)
# source: superset/reports/notifications/slack.py#L99-L113
Enable the SLACK_V2_API feature flag to use the newer SlackNotificationV2 implementation, which is recommended for new installations.
Webhook Notifications
The WebhookNotification class in superset/reports/notifications/webhook.py posts JSON payloads to external HTTP endpoints. This channel requires explicit feature flag activation.
Enable in superset_config.py:
FEATURE_FLAGS = {
"ALERT_REPORT_WEBHOOK": True,
}
For security, enforce HTTPS-only endpoints:
ALERT_REPORTS_WEBHOOK_HTTPS_ONLY = True # default in superset/config.py
The implementation constructs a POST request:
wh_url = self._get_webhook_url()
response = requests.post(wh_url, json=payload, timeout=60)
# source: superset/reports/notifications/webhook.py#L24-L27
If the feature flag is disabled, the system raises NotificationUnprocessableException when attempting to create webhook recipients.
Step-by-Step Implementation Guide
Enable Required Feature Flags
Add the following to your superset_config.py to unlock all notification channels:
FEATURE_FLAGS = {
"ALERT_REPORT_WEBHOOK": True, # Enable webhook notifications
"SLACK_V2_API": True, # Use modern Slack API
"ALERT_REPORTS": True, # Enable the reporting feature itself
}
Configure Backend Services
Ensure your Celery workers are running with the beat scheduler enabled, as the reporting engine relies on periodic tasks defined in superset/tasks/scheduler.py.
Configure SMTP and Slack tokens as shown in the previous sections, then restart the Superset workers to load the new configuration.
Create Alerts and Reports via UI
- Navigate to Settings → Alerts & Reports.
- Click + Report or + Alert.
- Configure the Schedule using a crontab expression (e.g.,
0 9 * * 1-5for 9 AM weekdays). - For Alerts, provide the SQL query and threshold logic.
- Add Recipients by selecting the channel type (Email, Slack, or Webhook) and entering the target address or URL.
Programmatic Creation via Python API
For infrastructure-as-code deployments, create schedules directly using the Superset ORM:
from superset.models.core import Database
from superset.reports.models import ReportSchedule, ReportRecipient, ReportRecipientType
from superset import db
# Retrieve target database
db_obj = db.session.query(Database).filter_by(database_name="production").one()
# Create the schedule
schedule = ReportSchedule(
type="Alert",
name="Revenue Drop Alert",
crontab="0 */6 * * *", # Every 6 hours
sql="SELECT SUM(revenue) FROM daily_metrics WHERE dt = CURRENT_DATE - 1",
validator_type="operator",
validator_config_json='{"op":"<","threshold":50000}',
database=db_obj,
active=True,
)
db.session.add(schedule)
db.session.commit()
# Attach email recipient
email_recipient = ReportRecipient(
type=ReportRecipientType.EMAIL,
recipient_config_json='{"target":"[email protected]"}',
report_schedule=schedule,
)
db.session.add(email_recipient)
db.session.commit()
Execution Flow and Celery Integration
Understanding the backend execution helps debug delivery failures. When a schedule fires, the following occurs:
- Celery Beat reads the
crontabfield fromReportScheduleand enqueues a task defined insuperset/tasks/scheduler.py. - The worker executes
execute_report_schedule(defined insuperset/commands/report/execute.py), which loads the schedule and creates aReportExecutionContext. - If
schedule.type == "Alert", the system instantiatesAlertCommandfromsuperset/commands/report/alert.pyto evaluate the SQL query against the configured validator. - Upon successful execution, the system generates a
ReportExecutionResultcontaining screenshots, CSV data, or PDF attachments. - The notification manager iterates over
schedule.recipientsand instantiates the appropriate notification class (EmailNotification,SlackNotification, orWebhookNotification) to dispatch the payload.
Testing and Debugging Notifications
Before deploying to production, validate your configuration using Superset's Python shell:
Test Email Delivery
from superset.reports.notifications.email import EmailContent, EmailNotification
from superset.reports.models import ReportRecipient, ReportRecipientType
content = EmailContent(
body="Test alert: Revenue threshold exceeded",
name="Revenue Alert",
url="https://superset.example.com/chart/123",
)
recipient = ReportRecipient(
type=ReportRecipientType.EMAIL,
recipient_config_json='{"target":"[email protected]"}',
)
notification = EmailNotification(content, recipient)
notification.send()
Test Slack Integration
from superset.reports.notifications.slack import SlackNotification
from superset.reports.models import ReportRecipient, ReportRecipientType
recipient = ReportRecipient(
type=ReportRecipientType.SLACK,
recipient_config_json='{"target":"#test-channel"}',
)
notification = SlackNotification(content, recipient)
notification.send()
Verify Alert Logic
Test your SQL threshold logic without triggering notifications:
from superset.commands.report.alert import AlertCommand
from superset.reports.models import ReportSchedule
import uuid
schedule = db.session.get(ReportSchedule, 42) # Your alert ID
command = AlertCommand(schedule, uuid.uuid4())
triggered, message = command.run()
print(f"Triggered: {triggered}, Message: {message}")
Summary
- Alerts execute SQL queries against thresholds using
AlertCommandinsuperset/commands/report/alert.py, while scheduled reports capture static snapshots of charts and dashboards. - Notification channels are implemented as distinct classes in
superset/reports/notifications/:EmailNotificationrequires SMTP configuration,SlackNotificationrequires a bot token, andWebhookNotificationrequires theALERT_REPORT_WEBHOOKfeature flag. - Configuration happens in
superset_config.pythrough standard SMTP variables (SMTP_HOST,SMTP_USER),SLACK_API_TOKEN, and feature flags likeALERT_REPORT_WEBHOOKandSLACK_V2_API. - Execution relies on Celery Beat reading
ReportSchedule.crontaband dispatching tasks viasuperset/commands/report/execute.py, which instantiates the appropriate notification classes based onReportRecipientType. - Programmatic access is available through the Superset ORM by creating
ReportScheduleandReportRecipientobjects directly insuperset/reports/models.py.
Frequently Asked Questions
How do I enable webhook notifications in Apache Superset?
Enable the ALERT_REPORT_WEBHOOK feature flag in superset_config.py by setting FEATURE_FLAGS = {"ALERT_REPORT_WEBHOOK": True}. Additionally, set ALERT_REPORTS_WEBHOOK_HTTPS_ONLY = True to restrict webhooks to HTTPS endpoints only. Once enabled, you can add webhook recipients in the Alerts & Reports UI by selecting "Webhook" and providing the target URL.
What SMTP settings are required for email alerts?
Configure the following variables in superset_config.py: SMTP_HOST, SMTP_PORT (typically 587 for TLS), SMTP_USER, SMTP_PASSWORD, and MAIL_DEFAULT_SENDER. Optionally customize EMAIL_REPORTS_SUBJECT_PREFIX to tag outgoing messages. These settings are consumed by EmailNotification in superset/reports/notifications/email.py when constructing messages via the send_email_smtp utility.
How does Superset determine if an alert should trigger?
The AlertCommand class in superset/commands/report/alert.py evaluates the alert SQL query and applies the configured validator. For NOT_NULL validators, it checks if the result is non-zero and not NaN. For OPERATOR validators, it compares the query result against a threshold using Python comparison functions. The run() method returns a tuple (triggered, message) indicating whether the notification should proceed.
Can I create alerts and reports programmatically instead of using the UI?
Yes, you can instantiate ReportSchedule and ReportRecipient objects directly from superset/reports/models.py. Create a schedule with type="Alert" or type="Report", set the crontab string, SQL query (for alerts), and validator configuration. Then append ReportRecipient instances with type=ReportRecipientType.EMAIL, SLACK, or WEBHOOK and the appropriate JSON configuration in recipient_config_json. Commit these to the database using the Superset application context.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →