Email Operator

Last updated: February 28, 2024

The EmailOperator allows you to send emails from your Airflow DAGs. It's a simple yet powerful way to get notified about the status of your tasks or to send custom reports.

Note: Before using the EmailOperator, ensure you have configured an email connection in your Airflow UI. Navigate to Admin -> Connections, click the '+' button, and fill in the details for an SMTP connection. The connection ID is typically smtp_default unless you specify otherwise.

Basic Usage

To send a basic email, you need to specify the recipient(s), subject, and content.

from airflow import DAG
from airflow.operators.email import EmailOperator
from datetime import datetime

with DAG(
    dag_id='email_example',
    start_date=datetime(2023, 1, 1),
    schedule_interval=None,
    catchup=False,
    tags=['email', 'example'],
) as dag:
    send_email_task = EmailOperator(
        task_id='send_welcome_email',
        to='recipient@example.com',
        subject='Welcome to Airflow!',
        html_content='''
        

Hello!

This is a welcome email sent from your Airflow DAG.

Best regards,

The Airflow Team

''', # You can specify a custom connection ID if you have more than one SMTP connection # conn_id='my_custom_smtp_connection', )

Parameters

The EmailOperator accepts several parameters:

Parameter Description Required Default
task_id The unique identifier for the task. Yes None
to A string or list of strings representing the email addresses of the recipients. Yes None
subject The subject line of the email. Yes None
html_content The body of the email in HTML format. No (either html_content or conn_id must be provided) None
conn_id The Airflow connection ID for the SMTP server. Defaults to smtp_default. No smtp_default
files A list of file paths to attach to the email. No []
cc A string or list of strings for CC recipients. No None
bcc A string or list of strings for BCC recipients. No None
mime_subtype The MIME subtype for the content. Typically 'plain' or 'html'. No 'plain'
custom_headers A dictionary of custom email headers. No None

Sending Plain Text Emails

If you prefer to send plain text emails, use the text_content parameter instead of html_content.

from airflow import DAG
from airflow.operators.email import EmailOperator
from datetime import datetime

with DAG(
    dag_id='email_text_example',
    start_date=datetime(2023, 1, 1),
    schedule_interval=None,
    catchup=False,
    tags=['email', 'text'],
) as dag:
    send_text_email_task = EmailOperator(
        task_id='send_status_update',
        to='admin@example.com',
        subject='Task Status Update',
        text_content='The data processing task has completed successfully.',
        mime_subtype='plain',
    )

Attaching Files

You can attach files to your emails by providing a list of file paths to the files parameter.

from airflow import DAG
from airflow.operators.email import EmailOperator
from datetime import datetime

with DAG(
    dag_id='email_attachment_example',
    start_date=datetime(2023, 1, 1),
    schedule_interval=None,
    catchup=False,
    tags=['email', 'attachment'],
) as dag:
    send_report_email = EmailOperator(
        task_id='send_daily_report',
        to='reporting@example.com',
        subject='Daily Report',
        html_content='Please find the daily report attached.',
        files=['/path/to/your/daily_report.csv', '/path/to/another/file.pdf'],
    )
Tip: For sensitive information in email content or attachments, consider using Airflow Variables or Connections to store them securely and access them within your DAG.

Dynamic Email Content

You can use Jinja templating to dynamically generate email content based on task parameters or Airflow variables.

from airflow import DAG
from airflow.operators.email import EmailOperator
from airflow.operators.bash import BashOperator
from airflow.utils.trigger_rule import TriggerRule
from datetime import datetime

with DAG(
    dag_id='dynamic_email_example',
    start_date=datetime(2023, 1, 1),
    schedule_interval='@daily',
    catchup=False,
    tags=['email', 'dynamic'],
) as dag:
    generate_report = BashOperator(
        task_id='generate_report',
        bash_command='echo "Processing data and generating report..." && sleep 5 && echo "Report generated: report_$(date +%Y%m%d).csv" > /tmp/report_file.txt',
    )

    send_dynamic_email = EmailOperator(
        task_id='send_dynamic_report_email',
        to='report_recipient@example.com',
        subject='Daily Data Processing Report - {{ ds }}',
        html_content='''
        

Data Processing Report for {{ ds }}

The daily data processing task has completed.

Details:

    {% for line in task_instance.xcom_pull(task_ids='generate_report', key='return_value').splitlines() %}
  • {{ line }}
  • {% endfor %}
''', trigger_rule=TriggerRule.ALL_SUCCESS, ) generate_report >> send_dynamic_email
Warning: Be cautious when including sensitive data directly in email subjects or bodies, even when templated. Ensure proper security measures are in place.

Common Pitfalls