This is an automated email from the ASF dual-hosted git repository.

jedcunningham pushed a commit to branch v2-2-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit fd5558fe9eb4c82f1aa49244deb75a6d500334bc
Author: ignaski <[email protected]>
AuthorDate: Fri Oct 29 12:10:49 2021 +0300

    Fixing ses email backend (#18042)
    
    (cherry picked from commit 1543dc28f4a2f1631dfaedd948e646a181ccf7ee)
---
 airflow/config_templates/config.yml              |  8 +++++
 airflow/config_templates/default_airflow.cfg     |  5 +++
 airflow/providers/amazon/aws/utils/emailer.py    |  3 +-
 airflow/utils/email.py                           | 10 ++++--
 docs/apache-airflow/howto/email-config.rst       |  7 ++++
 tests/providers/amazon/aws/utils/test_emailer.py | 42 +++++++++++++-----------
 tests/utils/test_email.py                        | 14 ++++++++
 7 files changed, 66 insertions(+), 23 deletions(-)

diff --git a/airflow/config_templates/config.yml 
b/airflow/config_templates/config.yml
index 6fa38d7..a70854e 100644
--- a/airflow/config_templates/config.yml
+++ b/airflow/config_templates/config.yml
@@ -1353,6 +1353,14 @@
       example: "/path/to/my_html_content_template_file"
       default: ~
       see_also: ":doc:`Email Configuration </howto/email-config>`"
+    - name: from_email
+      description: |
+        Email address that will be used as sender address.
+        It can either be raw email or the complete address in a format 
``Sender Name <[email protected]>``
+      version_added: 2.3.0
+      type: string
+      example: "Airflow <[email protected]>"
+      default: ~
 
 - name: smtp
   description: |
diff --git a/airflow/config_templates/default_airflow.cfg 
b/airflow/config_templates/default_airflow.cfg
index 7124d95..6a5449b 100644
--- a/airflow/config_templates/default_airflow.cfg
+++ b/airflow/config_templates/default_airflow.cfg
@@ -681,6 +681,11 @@ default_email_on_failure = True
 # Example: html_content_template = /path/to/my_html_content_template_file
 # html_content_template =
 
+# Email address that will be used as sender address.
+# It can either be raw email or the complete address in a format ``Sender Name 
<[email protected]>``
+# Example: from_email = Airflow <[email protected]>
+# from_email =
+
 [smtp]
 
 # If you want airflow to send emails on retries, failure, and you want to use
diff --git a/airflow/providers/amazon/aws/utils/emailer.py 
b/airflow/providers/amazon/aws/utils/emailer.py
index d098892..fc34835 100644
--- a/airflow/providers/amazon/aws/utils/emailer.py
+++ b/airflow/providers/amazon/aws/utils/emailer.py
@@ -23,6 +23,7 @@ from airflow.providers.amazon.aws.hooks.ses import SESHook
 
 
 def send_email(
+    from_email: str,
     to: Union[List[str], str],
     subject: str,
     html_content: str,
@@ -37,7 +38,7 @@ def send_email(
     """Email backend for SES."""
     hook = SESHook(aws_conn_id=conn_id)
     hook.send_email(
-        mail_from=None,
+        mail_from=from_email,
         to=to,
         subject=subject,
         html_content=html_content,
diff --git a/airflow/utils/email.py b/airflow/utils/email.py
index 7d17027..50f2415 100644
--- a/airflow/utils/email.py
+++ b/airflow/utils/email.py
@@ -49,6 +49,8 @@ def send_email(
     """Send email using backend specified in EMAIL_BACKEND."""
     backend = conf.getimport('email', 'EMAIL_BACKEND')
     backend_conn_id = conn_id or conf.get("email", "EMAIL_CONN_ID")
+    from_email = conf.get('email', 'from_email', fallback=None)
+
     to_list = get_email_address_list(to)
     to_comma_separated = ", ".join(to_list)
 
@@ -63,6 +65,7 @@ def send_email(
         mime_subtype=mime_subtype,
         mime_charset=mime_charset,
         conn_id=backend_conn_id,
+        from_email=from_email,
         **kwargs,
     )
 
@@ -78,6 +81,7 @@ def send_email_smtp(
     mime_subtype: str = 'mixed',
     mime_charset: str = 'utf-8',
     conn_id: str = "smtp_default",
+    from_email: str = None,
     **kwargs,
 ):
     """
@@ -87,8 +91,10 @@ def send_email_smtp(
     """
     smtp_mail_from = conf.get('smtp', 'SMTP_MAIL_FROM')
 
+    mail_from = smtp_mail_from or from_email
+
     msg, recipients = build_mime_message(
-        mail_from=smtp_mail_from,
+        mail_from=mail_from,
         to=to,
         subject=subject,
         html_content=html_content,
@@ -99,7 +105,7 @@ def send_email_smtp(
         mime_charset=mime_charset,
     )
 
-    send_mime_email(e_from=smtp_mail_from, e_to=recipients, mime_msg=msg, 
conn_id=conn_id, dryrun=dryrun)
+    send_mime_email(e_from=mail_from, e_to=recipients, mime_msg=msg, 
conn_id=conn_id, dryrun=dryrun)
 
 
 def build_mime_message(
diff --git a/docs/apache-airflow/howto/email-config.rst 
b/docs/apache-airflow/howto/email-config.rst
index 67e26a7..af7b3cf 100644
--- a/docs/apache-airflow/howto/email-config.rst
+++ b/docs/apache-airflow/howto/email-config.rst
@@ -29,6 +29,8 @@ in the ``[email]`` section.
   subject_template = /path/to/my_subject_template_file
   html_content_template = /path/to/my_html_content_template_file
 
+You can configure sender's email address by setting ``from_email`` in the 
``[email]`` section.
+
 To configure SMTP settings, checkout the :ref:`SMTP <config:smtp>` section in 
the standard configuration.
 If you do not want to store the SMTP credentials in the config or in the 
environment variables, you can create a
 connection called ``smtp_default`` of ``Email`` type, or choose a custom 
connection name and set the ``email_conn_id`` with it's name in
@@ -91,6 +93,9 @@ or
    name and set it in ``email_conn_id`` of  'Email' type. Only login and 
password
    are used from the connection.
 
+4. Configure sender's email address and name either by exporting the 
environment variables ``SENDGRID_MAIL_FROM`` and ``SENDGRID_MAIL_SENDER`` or
+   in your ``airflow.cfg`` by setting ``from_email`` in the ``[email]`` 
section.
+
 .. _email-configuration-ses:
 
 Send email using AWS SES
@@ -116,3 +121,5 @@ Follow the steps below to enable it:
 
 3. Create a connection called ``aws_default``, or choose a custom connection
    name and set it in ``email_conn_id``. The type of connection should be 
``Amazon Web Services``.
+
+4. Configure sender's email address in your ``airflow.cfg`` by setting 
``from_email`` in the ``[email]`` section.
diff --git a/tests/providers/amazon/aws/utils/test_emailer.py 
b/tests/providers/amazon/aws/utils/test_emailer.py
index 3d99573..bcbbd4e 100644
--- a/tests/providers/amazon/aws/utils/test_emailer.py
+++ b/tests/providers/amazon/aws/utils/test_emailer.py
@@ -16,27 +16,29 @@
 # specific language governing permissions and limitations
 # under the License.
 #
-
-from unittest import mock
+from unittest import TestCase, mock
 
 from airflow.providers.amazon.aws.utils.emailer import send_email
 
 
[email protected]("airflow.providers.amazon.aws.utils.emailer.SESHook")
-def test_send_email(mock_hook):
-    send_email(
-        to="[email protected]",
-        subject="subject",
-        html_content="content",
-    )
-    mock_hook.return_value.send_email.assert_called_once_with(
-        mail_from=None,
-        to="[email protected]",
-        subject="subject",
-        html_content="content",
-        bcc=None,
-        cc=None,
-        files=None,
-        mime_charset="utf-8",
-        mime_subtype="mixed",
-    )
+class TestSendEmailSes(TestCase):
+    @mock.patch("airflow.providers.amazon.aws.utils.emailer.SESHook")
+    def test_send_ses_email(self, mock_hook):
+        send_email(
+            from_email="From Test <[email protected]>",
+            to="[email protected]",
+            subject="subject",
+            html_content="content",
+        )
+
+        mock_hook.return_value.send_email.assert_called_once_with(
+            mail_from="From Test <[email protected]>",
+            to="[email protected]",
+            subject="subject",
+            html_content="content",
+            bcc=None,
+            cc=None,
+            files=None,
+            mime_charset="utf-8",
+            mime_subtype="mixed",
+        )
diff --git a/tests/utils/test_email.py b/tests/utils/test_email.py
index 28d4328..b458bbd 100644
--- a/tests/utils/test_email.py
+++ b/tests/utils/test_email.py
@@ -99,9 +99,23 @@ class TestEmail(unittest.TestCase):
             mime_charset='utf-8',
             mime_subtype='mixed',
             conn_id='smtp_default',
+            from_email=None,
         )
         assert not mock_send_email.called
 
+    @mock.patch('airflow.utils.email.send_email_smtp')
+    @conf_vars(
+        {
+            ('email', 'email_backend'): 
'tests.utils.test_email.send_email_test',
+            ('email', 'from_email'): '[email protected]',
+        }
+    )
+    def test_custom_backend_sender(self, mock_send_email_smtp):
+        utils.email.send_email('to', 'subject', 'content')
+        _, call_kwargs = send_email_test.call_args
+        assert call_kwargs['from_email'] == '[email protected]'
+        assert not mock_send_email_smtp.called
+
     def test_build_mime_message(self):
         mail_from = '[email protected]'
         mail_to = '[email protected]'

Reply via email to