Email Notification System
The worker emails users when selected Celery tasks finish. Only tasks decorated with
@email_notification send mail, so parallel subtasks stay silent and a run produces one summary
email rather than many. Sending is non-blocking, runs on both success and permanent failure, and
no-ops if SMTP is not configured.
Configuration
Set these in the worker deployment. Any SMTP provider works; the example is SendGrid:
If any SMTP variable is missing, EmailService.is_configured is false and notifications are
skipped with a log line rather than an error.
Opting a task in
Decorate a task with @email_notification, choosing a template. Without the decorator, no mail is
sent.
Templates: EmailTemplate.TASK_COMPLETION (generic) or EmailTemplate.TEST_EXECUTION_SUMMARY
(runs). The optional subject_template uses the same context variables.
Current usage:
collect_results—TEST_EXECUTION_SUMMARYemail_notification_test—TASK_COMPLETION- per-test execution and utility tasks — no decorator
Parallel test execution runs an async batch inside one Celery task (not a Celery chord). When the
batch finishes, trigger_results_collection schedules collect_results with the result list, so
the summary email path is the same as for sequential runs. See tasks/execution/shared.py and
tasks/execution/results.py.
Template variables
The decorator provides these to every template:
recipient_name— user’s display nametask_name— human-readable task nametask_idstatus—successorfailedexecution_time— formatted durationerror_message— for failed tasksfrontend_urlcompleted_at
Anything the task returns is merged in, so a summary template can use extra fields:
How it works
EmailService (notifications/email/service.py, exported as the email_service singleton from
rhesis.backend.notifications) loads SMTP config from the environment and renders Jinja2 templates.
On success or permanent failure, BaseTask (in its on_success / on_failure hooks) loads the
task owner from the database, renders the template with the task’s return values and timing, and
calls email_service.send_email(...). Users with placeholder addresses (*@placeholder.rhesis.ai)
are skipped, and send errors are logged without failing the task.
Troubleshooting
- No emails — check worker logs for
SMTP configuration incomplete, confirm theSMTP_*variables reach the worker pods, and verify the recipient has a real (non-placeholder) address. - Auth errors — recheck
SMTP_USER/SMTP_PASSWORD(SendGrid uses the literalapikeyas the username) and that port 587 is reachable from the worker. - Missing result links — set
FRONTEND_URLand returntest_run_idfrom the task.
Security
Emails go only to the task owner, and multi-tenant scoping prevents cross-organization delivery. Bodies carry status and timing, not task result data. SMTP connections use STARTTLS and credentials are stored as worker secrets.