codecov[bot]: # [Codecov](https://codecov.io/gh/sendgrid/sendgrid-python/pull/631?src=pr&el=h1) Report
> Merging [#631](https://codecov.io/gh/sendgrid/sendgrid-python/pull/631?src=pr&el=desc) into [master](https://codecov.io/gh/sendgrid/sendgrid-python/commit/f132e5ba71391f2390d94fb8743e5cb2aed0beb9?src=pr&el=desc) will **increase** coverage by `0.09%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/sendgrid/sendgrid-python/pull/631/graphs/tree.svg?width=650&token=Yq0yTs1Nfq&height=150&src=pr)](https://codecov.io/gh/sendgrid/sendgrid-python/pull/631?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #631      +/-   ##
==========================================
+ Coverage   84.77%   84.86%   +0.09%     
==========================================
  Files          35       35              
  Lines        1156     1163       +7     
  Branches      172      173       +1     
==========================================
+ Hits          980      987       +7     
  Misses         90       90              
  Partials       86       86
```


| [Impacted Files](https://codecov.io/gh/sendgrid/sendgrid-python/pull/631?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [sendgrid/helpers/mail/mail.py](https://codecov.io/gh/sendgrid/sendgrid-python/pull/631/diff?src=pr&el=tree#diff-c2VuZGdyaWQvaGVscGVycy9tYWlsL21haWwucHk=) | `93.97% <100%> (+0.26%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/sendgrid/sendgrid-python/pull/631?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/sendgrid/sendgrid-python/pull/631?src=pr&el=footer). Last update [f132e5b...bb417a1](https://codecov.io/gh/sendgrid/sendgrid-python/pull/631?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

diff --git a/sendgrid/helpers/mail/mail.py b/sendgrid/helpers/mail/mail.py
index f374e6a..c27fc72 100644
--- a/sendgrid/helpers/mail/mail.py
+++ b/sendgrid/helpers/mail/mail.py
@@ -1,6 +1,8 @@
 """v3/mail/send response body builder"""
 from .personalization import Personalization
 from .header import Header
+from .email import Email
+from .content import Content
 
 
 class Mail(object):
@@ -141,3 +143,28 @@ class Mail(object):
 
         return {key: value for key, value in mail.items()
                 if value is not None and value != [] and value != {}}
+
+    @classmethod
+    def from_EmailMessage(cls, message):
+        """Create a Mail object from an instance of
+        email.message.EmailMessage.
+        :type message: email.message.EmailMessage
+        :rtype: Mail
+        """
+        mail = cls(
+            from_email=Email(message.get('From')),
+            subject=message.get('Subject'),
+            to_email=Email(message.get('To')),
+        )
+        try:
+            body = message.get_content()
+        except AttributeError:
+            # Python2
+            body = message.get_payload()
+        mail.add_content(Content(
+            message.get_content_type(),
+            body.strip()
+        ))
+        for k, v in message.items():
+            mail.add_header(Header(k, v))
+        return mail

Feature request: Support for sending email.message.EmailMessage
I am working on integrating SendGrid into an application where I already have email messages as [email.message.EmailMessage](https://docs.python.org/3.6/library/email.message.html#email.message.EmailMessage), it would be really awesome if there was a way for me to send an `EmailMessage` directly rather than having to reconstruct .
diff --git a/test/test_mail.py b/test/test_mail.py
index 98af29a..8ebe3eb 100644
--- a/test/test_mail.py
+++ b/test/test_mail.py
@@ -2,6 +2,13 @@
 import json
 import unittest
 
+try:
+    from email.message import EmailMessage
+except ImportError:
+    # Python2
+    from email import message
+    EmailMessage = message.Message
+
 from sendgrid.helpers.mail import (
     ASM,
     APIKeyIncludedException,
@@ -557,3 +564,26 @@ class UnitTests(unittest.TestCase):
     def test_directly_setting_substitutions(self):
         personalization = Personalization()
         personalization.substitutions = [{'a': 0}]
+
+    def test_from_emailmessage(self):
+        message = EmailMessage()
+        body = 'message that is not urgent'
+        try:
+            message.set_content(body)
+        except AttributeError:
+            # Python2
+            message.set_payload(body)
+        message.set_default_type('text/plain')
+        message['Subject'] = 'URGENT TITLE'
+        message['From'] = 'test@example.com'
+        message['To'] = 'test@sendgrid.com'
+        mail = Mail.from_EmailMessage(message)
+        self.assertEqual(mail.subject, 'URGENT TITLE')
+        self.assertEqual(mail.from_email.email, 'test@example.com')
+        self.assertEqual(len(mail.personalizations), 1)
+        self.assertEqual(len(mail.personalizations[0].tos), 1)
+        self.assertEqual(mail.personalizations[0].tos[0], {'email': 'test@sendgrid.com'})
+        self.assertEqual(len(mail.contents), 1)
+        content = mail.contents[0]
+        self.assertEqual(content.type, 'text/plain')
+        self.assertEqual(content.value, 'message that is not urgent')

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest>=6.0.0 numpy>=1.16.0 pandas>=1.0.0
apt-get update apt-get install -y gcc
3.9
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
exceptiongroup==1.2.2
iniconfig==2.1.0
numpy==2.0.2
packaging==24.2
pandas==2.2.3
pluggy==1.5.0
pytest==8.3.5
python-dateutil==2.9.0.post0
python-http-client==3.3.7
pytz==2025.2
-e git+https://github.com/sendgrid/sendgrid-python.git@33a35765cffee71c56fd91a5561f39934b107cab#egg=sendgrid
six==1.17.0
tomli==2.2.1
tzdata==2025.2

name: sendgrid-python
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - exceptiongroup==1.2.2
      - iniconfig==2.1.0
      - numpy==2.0.2
      - packaging==24.2
      - pandas==2.2.3
      - pluggy==1.5.0
      - pytest==8.3.5
      - python-dateutil==2.9.0.post0
      - python-http-client==3.3.7
      - pytz==2025.2
      - six==1.17.0
      - tomli==2.2.1
      - tzdata==2025.2
prefix: /opt/conda/envs/sendgrid-python

test/test_mail.py::UnitTests::test_from_emailmessage
test/test_mail.py::UnitTests::test_asm_display_group_limit test/test_mail.py::UnitTests::test_directly_setting_substitutions test/test_mail.py::UnitTests::test_disable_tracking test/test_mail.py::UnitTests::test_helloEmail test/test_mail.py::UnitTests::test_helloEmailAdditionalContent test/test_mail.py::UnitTests::test_kitchenSink test/test_mail.py::UnitTests::test_sendgridAPIKey test/test_mail.py::UnitTests::test_unicode_values_in_substitutions_helper
sendgrid/helpers/mail/mail.py
sendgrid/helpers/mail/mail.py