aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/sendgrid/helpers/mail/mail.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/sendgrid/helpers/mail/mail.py')
-rw-r--r--.venv/lib/python3.12/site-packages/sendgrid/helpers/mail/mail.py1041
1 files changed, 1041 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/sendgrid/helpers/mail/mail.py b/.venv/lib/python3.12/site-packages/sendgrid/helpers/mail/mail.py
new file mode 100644
index 00000000..2472ad7d
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/sendgrid/helpers/mail/mail.py
@@ -0,0 +1,1041 @@
+"""Twilio SendGrid v3/mail/send response body builder"""
+from .bcc_email import Bcc
+from .cc_email import Cc
+from .content import Content
+from .custom_arg import CustomArg
+from .dynamic_template_data import DynamicTemplateData
+from .email import Email
+from .from_email import From
+from .header import Header
+from .mime_type import MimeType
+from .personalization import Personalization
+from .reply_to import ReplyTo
+from .send_at import SendAt
+from .subject import Subject
+from .substitution import Substitution
+from .template_id import TemplateId
+from .to_email import To
+
+
+class Mail(object):
+ """Creates the response body for v3/mail/send"""
+
+ def __init__(
+ self,
+ from_email=None,
+ to_emails=None,
+ subject=None,
+ plain_text_content=None,
+ html_content=None,
+ amp_html_content=None,
+ global_substitutions=None,
+ is_multiple=False):
+ """
+ Creates the response body for a v3/mail/send API call
+
+ :param from_email: The email address of the sender
+ :type from_email: From, tuple, optional
+ :param subject: The subject of the email
+ :type subject: Subject, optional
+ :param to_emails: The email address of the recipient
+ :type to_emails: To, str, tuple, list(str), list(tuple),
+ list(To), optional
+ :param plain_text_content: The plain text body of the email
+ :type plain_text_content: string, optional
+ :param html_content: The html body of the email
+ :type html_content: string, optional
+ :param amp_html_content: The amp-html body of the email
+ :type amp_html_content: string, optional
+ """
+ self._attachments = None
+ self._categories = None
+ self._contents = None
+ self._custom_args = None
+ self._headers = None
+ self._personalizations = []
+ self._sections = None
+ self._asm = None
+ self._batch_id = None
+ self._from_email = None
+ self._ip_pool_name = None
+ self._mail_settings = None
+ self._reply_to = None
+ self._reply_to_list = None
+ self._send_at = None
+ self._subject = None
+ self._template_id = None
+ self._tracking_settings = None
+
+ # Minimum required data to send a single email
+ if from_email is not None:
+ self.from_email = from_email
+ if to_emails is not None:
+ self.add_to(to_emails, global_substitutions, is_multiple)
+ if subject is not None:
+ self.subject = subject
+ if plain_text_content is not None:
+ self.add_content(plain_text_content, MimeType.text)
+ if amp_html_content is not None:
+ self.add_content(amp_html_content, MimeType.amp)
+ if html_content is not None:
+ self.add_content(html_content, MimeType.html)
+
+ def __str__(self):
+ """A JSON-ready string representation of this Mail object.
+
+ :returns: A JSON-ready string representation of this Mail object.
+ :rtype: string
+ """
+ return str(self.get())
+
+ def _ensure_append(self, new_items, append_to, index=0):
+ """Ensure an item is appended to a list or create a new empty list
+
+ :param new_items: the item(s) to append
+ :type new_items: list(obj)
+ :param append_to: the list on which to append the items
+ :type append_to: list()
+ :param index: index of the list on which to append the items
+ :type index: int
+ """
+ append_to = append_to or []
+ append_to.insert(index, new_items)
+ return append_to
+
+ def _ensure_insert(self, new_items, insert_to):
+ """Ensure an item is inserted to a list or create a new empty list
+
+ :param new_items: the item(s) to insert
+ :type new_items: list(obj)
+ :param insert_to: the list on which to insert the items at index 0
+ :type insert_to: list()
+ """
+ insert_to = insert_to or []
+ insert_to.insert(0, new_items)
+ return insert_to
+
+ def _flatten_dicts(self, dicts):
+ """Flatten a dict
+
+ :param dicts: Flatten a dict
+ :type dicts: list(dict)
+ """
+ d = dict()
+ list_of_dicts = [d.get() for d in dicts or []]
+ return {k: v for d in list_of_dicts for k, v in d.items()}
+
+ def _get_or_none(self, from_obj):
+ """Get the JSON representation of the object, else return None
+
+ :param from_obj: Get the JSON representation of the object,
+ else return None
+ :type from_obj: obj
+ """
+ return from_obj.get() if from_obj is not None else None
+
+ def _set_emails(
+ self, emails, global_substitutions=None, is_multiple=False, p=0):
+ """Adds emails to the Personalization object
+
+ :param emails: An Email or list of Email objects
+ :type emails: Email, list(Email)
+ :param global_substitutions: A dict of substitutions for all recipients
+ :type global_substitutions: dict
+ :param is_multiple: Create a new personalization for each recipient
+ :type is_multiple: bool
+ :param p: p is the Personalization object or Personalization object
+ index
+ :type p: Personalization, integer, optional
+ """
+ # Send multiple emails to multiple recipients
+ if is_multiple is True:
+ if isinstance(emails, list):
+ for email in emails:
+ personalization = Personalization()
+ personalization.add_email(email)
+ self.add_personalization(personalization)
+ else:
+ personalization = Personalization()
+ personalization.add_email(emails)
+ self.add_personalization(personalization)
+ if global_substitutions is not None:
+ if isinstance(global_substitutions, list):
+ for substitution in global_substitutions:
+ for p in self.personalizations:
+ p.add_substitution(substitution)
+ else:
+ for p in self.personalizations:
+ p.add_substitution(global_substitutions)
+ else:
+ try:
+ personalization = self._personalizations[p]
+ has_internal_personalization = True
+ except IndexError:
+ personalization = Personalization()
+ has_internal_personalization = False
+
+ if isinstance(emails, list):
+ for email in emails:
+ personalization.add_email(email)
+ else:
+ personalization.add_email(emails)
+
+ if global_substitutions is not None:
+ if isinstance(global_substitutions, list):
+ for substitution in global_substitutions:
+ personalization.add_substitution(substitution)
+ else:
+ personalization.add_substitution(global_substitutions)
+
+ if not has_internal_personalization:
+ self.add_personalization(personalization, index=p)
+
+ @property
+ def personalizations(self):
+ """A list of one or more Personalization objects
+
+ :rtype: list(Personalization)
+ """
+ return self._personalizations
+
+ def add_personalization(self, personalization, index=0):
+ """Add a Personalization object
+
+ :param personalization: Add a Personalization object
+ :type personalization: Personalization
+ :param index: The index where to add the Personalization
+ :type index: int
+ """
+ self._personalizations = self._ensure_append(
+ personalization, self._personalizations, index)
+
+ @property
+ def to(self):
+ pass
+
+ @to.setter
+ def to(self, to_emails, global_substitutions=None, is_multiple=False, p=0):
+ """Adds To objects to the Personalization object
+
+ :param to_emails: The email addresses of all recipients
+ :type to_emails: To, str, tuple, list(str), list(tuple), list(To)
+ :param global_substitutions: A dict of substitutions for all recipients
+ :type global_substitutions: dict
+ :param is_multiple: Create a new personalization for each recipient
+ :type is_multiple: bool
+ :param p: p is the Personalization object or Personalization object
+ index
+ :type p: Personalization, integer, optional
+ """
+ if isinstance(to_emails, list):
+ for email in to_emails:
+ if isinstance(email, str):
+ email = To(email, None)
+ if isinstance(email, tuple):
+ email = To(email[0], email[1])
+ self.add_to(email, global_substitutions, is_multiple, p)
+ else:
+ if isinstance(to_emails, str):
+ to_emails = To(to_emails, None)
+ if isinstance(to_emails, tuple):
+ to_emails = To(to_emails[0], to_emails[1])
+ self.add_to(to_emails, global_substitutions, is_multiple, p)
+
+ def add_to(
+ self, to_email, global_substitutions=None, is_multiple=False, p=0):
+ """Adds a To object to the Personalization object
+
+ :param to_email: A To object
+ :type to_email: To, str, tuple, list(str), list(tuple), list(To)
+ :param global_substitutions: A dict of substitutions for all recipients
+ :type global_substitutions: dict
+ :param is_multiple: Create a new personalization for each recipient
+ :type is_multiple: bool
+ :param p: p is the Personalization object or Personalization object
+ index
+ :type p: Personalization, integer, optional
+ """
+
+ if isinstance(to_email, list):
+ for email in to_email:
+ if isinstance(email, str):
+ email = To(email, None)
+ elif isinstance(email, tuple):
+ email = To(email[0], email[1])
+ elif not isinstance(email, Email):
+ raise ValueError(
+ 'Please use a To/Cc/Bcc, tuple, or a str for a to_email list.'
+ )
+ self._set_emails(email, global_substitutions, is_multiple, p)
+ else:
+ if isinstance(to_email, str):
+ to_email = To(to_email, None)
+ if isinstance(to_email, tuple):
+ to_email = To(to_email[0], to_email[1])
+ if isinstance(to_email, Email):
+ p = to_email.personalization
+ self._set_emails(to_email, global_substitutions, is_multiple, p)
+
+ @property
+ def cc(self):
+ pass
+
+ @cc.setter
+ def cc(self, cc_emails, global_substitutions=None, is_multiple=False, p=0):
+ """Adds Cc objects to the Personalization object
+
+ :param cc_emails: An Cc or list of Cc objects
+ :type cc_emails: Cc, list(Cc), tuple
+ :param global_substitutions: A dict of substitutions for all recipients
+ :type global_substitutions: dict
+ :param is_multiple: Create a new personalization for each recipient
+ :type is_multiple: bool
+ :param p: p is the Personalization object or Personalization object
+ index
+ :type p: Personalization, integer, optional
+ """
+ if isinstance(cc_emails, list):
+ for email in cc_emails:
+ if isinstance(email, str):
+ email = Cc(email, None)
+ if isinstance(email, tuple):
+ email = Cc(email[0], email[1])
+ self.add_cc(email, global_substitutions, is_multiple, p)
+ else:
+ if isinstance(cc_emails, str):
+ cc_emails = Cc(cc_emails, None)
+ if isinstance(cc_emails, tuple):
+ cc_emails = To(cc_emails[0], cc_emails[1])
+ self.add_cc(cc_emails, global_substitutions, is_multiple, p)
+
+ def add_cc(
+ self, cc_email, global_substitutions=None, is_multiple=False, p=0):
+ """Adds a Cc object to the Personalization object
+
+ :param to_emails: An Cc object
+ :type to_emails: Cc
+ :param global_substitutions: A dict of substitutions for all recipients
+ :type global_substitutions: dict
+ :param is_multiple: Create a new personalization for each recipient
+ :type is_multiple: bool
+ :param p: p is the Personalization object or Personalization object
+ index
+ :type p: Personalization, integer, optional
+ """
+ if isinstance(cc_email, str):
+ cc_email = Cc(cc_email, None)
+ if isinstance(cc_email, tuple):
+ cc_email = Cc(cc_email[0], cc_email[1])
+ if isinstance(cc_email, Email):
+ p = cc_email.personalization
+ self._set_emails(
+ cc_email, global_substitutions, is_multiple=is_multiple, p=p)
+
+ @property
+ def bcc(self):
+ pass
+
+ @bcc.setter
+ def bcc(
+ self,
+ bcc_emails,
+ global_substitutions=None,
+ is_multiple=False,
+ p=0):
+ """Adds Bcc objects to the Personalization object
+
+ :param bcc_emails: An Bcc or list of Bcc objects
+ :type bcc_emails: Bcc, list(Bcc), tuple
+ :param global_substitutions: A dict of substitutions for all recipients
+ :type global_substitutions: dict
+ :param is_multiple: Create a new personalization for each recipient
+ :type is_multiple: bool
+ :param p: p is the Personalization object or Personalization object
+ index
+ :type p: Personalization, integer, optional
+ """
+ if isinstance(bcc_emails, list):
+ for email in bcc_emails:
+ if isinstance(email, str):
+ email = Bcc(email, None)
+ if isinstance(email, tuple):
+ email = Bcc(email[0], email[1])
+ self.add_bcc(email, global_substitutions, is_multiple, p)
+ else:
+ if isinstance(bcc_emails, str):
+ bcc_emails = Bcc(bcc_emails, None)
+ if isinstance(bcc_emails, tuple):
+ bcc_emails = Bcc(bcc_emails[0], bcc_emails[1])
+ self.add_bcc(bcc_emails, global_substitutions, is_multiple, p)
+
+ def add_bcc(
+ self,
+ bcc_email,
+ global_substitutions=None,
+ is_multiple=False,
+ p=0):
+ """Adds a Bcc object to the Personalization object
+
+ :param to_emails: An Bcc object
+ :type to_emails: Bcc
+ :param global_substitutions: A dict of substitutions for all recipients
+ :type global_substitutions: dict
+ :param is_multiple: Create a new personalization for each recipient
+ :type is_multiple: bool
+ :param p: p is the Personalization object or Personalization object
+ index
+ :type p: Personalization, integer, optional
+ """
+ if isinstance(bcc_email, str):
+ bcc_email = Bcc(bcc_email, None)
+ if isinstance(bcc_email, tuple):
+ bcc_email = Bcc(bcc_email[0], bcc_email[1])
+ if isinstance(bcc_email, Email):
+ p = bcc_email.personalization
+ self._set_emails(
+ bcc_email,
+ global_substitutions,
+ is_multiple=is_multiple,
+ p=p)
+
+ @property
+ def subject(self):
+ """The global Subject object
+
+ :rtype: Subject
+ """
+ return self._subject
+
+ @subject.setter
+ def subject(self, value):
+ """The subject of the email(s)
+
+ :param value: The subject of the email(s)
+ :type value: Subject, string
+ """
+ if isinstance(value, Subject):
+ if value.personalization is not None:
+ try:
+ personalization = \
+ self._personalizations[value.personalization]
+ has_internal_personalization = True
+ except IndexError:
+ personalization = Personalization()
+ has_internal_personalization = False
+ personalization.subject = value.subject
+
+ if not has_internal_personalization:
+ self.add_personalization(
+ personalization,
+ index=value.personalization)
+ else:
+ self._subject = value
+ else:
+ self._subject = Subject(value)
+
+ @property
+ def headers(self):
+ """A list of global Header objects
+
+ :rtype: list(Header)
+ """
+ return self._headers
+
+ @property
+ def header(self):
+ pass
+
+ @header.setter
+ def header(self, headers):
+ """Add headers to the email
+
+ :param value: A list of Header objects or a dict of header key/values
+ :type value: Header, list(Header), dict
+ """
+ if isinstance(headers, list):
+ for h in headers:
+ self.add_header(h)
+ else:
+ self.add_header(headers)
+
+ def add_header(self, header):
+ """Add headers to the email globaly or to a specific Personalization
+
+ :param value: A Header object or a dict of header key/values
+ :type value: Header, dict
+ """
+ if header.personalization is not None:
+ try:
+ personalization = \
+ self._personalizations[header.personalization]
+ has_internal_personalization = True
+ except IndexError:
+ personalization = Personalization()
+ has_internal_personalization = False
+ if isinstance(header, dict):
+ (k, v) = list(header.items())[0]
+ personalization.add_header(Header(k, v))
+ else:
+ personalization.add_header(header)
+
+ if not has_internal_personalization:
+ self.add_personalization(
+ personalization,
+ index=header.personalization)
+ else:
+ if isinstance(header, dict):
+ (k, v) = list(header.items())[0]
+ self._headers = self._ensure_append(
+ Header(k, v), self._headers)
+ else:
+ self._headers = self._ensure_append(header, self._headers)
+
+ @property
+ def substitution(self):
+ pass
+
+ @substitution.setter
+ def substitution(self, substitution):
+ """Add substitutions to the email
+
+ :param value: Add substitutions to the email
+ :type value: Substitution, list(Substitution)
+ """
+ if isinstance(substitution, list):
+ for s in substitution:
+ self.add_substitution(s)
+ else:
+ self.add_substitution(substitution)
+
+ def add_substitution(self, substitution):
+ """Add a substitution to the email
+
+ :param value: Add a substitution to the email
+ :type value: Substitution
+ """
+ if substitution.personalization:
+ try:
+ personalization = \
+ self._personalizations[substitution.personalization]
+ has_internal_personalization = True
+ except IndexError:
+ personalization = Personalization()
+ has_internal_personalization = False
+ personalization.add_substitution(substitution)
+
+ if not has_internal_personalization:
+ self.add_personalization(
+ personalization, index=substitution.personalization)
+ else:
+ if isinstance(substitution, list):
+ for s in substitution:
+ for p in self.personalizations:
+ p.add_substitution(s)
+ else:
+ for p in self.personalizations:
+ p.add_substitution(substitution)
+
+ @property
+ def custom_args(self):
+ """A list of global CustomArg objects
+
+ :rtype: list(CustomArg)
+ """
+ return self._custom_args
+
+ @property
+ def custom_arg(self):
+ return self._custom_args
+
+ @custom_arg.setter
+ def custom_arg(self, custom_arg):
+ """Add custom args to the email
+
+ :param value: A list of CustomArg objects or a dict of custom arg
+ key/values
+ :type value: CustomArg, list(CustomArg), dict
+ """
+ if isinstance(custom_arg, list):
+ for c in custom_arg:
+ self.add_custom_arg(c)
+ else:
+ self.add_custom_arg(custom_arg)
+
+ def add_custom_arg(self, custom_arg):
+ """Add custom args to the email globaly or to a specific Personalization
+
+ :param value: A CustomArg object or a dict of custom arg key/values
+ :type value: CustomArg, dict
+ """
+ if custom_arg.personalization is not None:
+ try:
+ personalization = \
+ self._personalizations[custom_arg.personalization]
+ has_internal_personalization = True
+ except IndexError:
+ personalization = Personalization()
+ has_internal_personalization = False
+ if isinstance(custom_arg, dict):
+ (k, v) = list(custom_arg.items())[0]
+ personalization.add_custom_arg(CustomArg(k, v))
+ else:
+ personalization.add_custom_arg(custom_arg)
+
+ if not has_internal_personalization:
+ self.add_personalization(
+ personalization, index=custom_arg.personalization)
+ else:
+ if isinstance(custom_arg, dict):
+ (k, v) = list(custom_arg.items())[0]
+ self._custom_args = self._ensure_append(
+ CustomArg(k, v), self._custom_args)
+ else:
+ self._custom_args = self._ensure_append(
+ custom_arg, self._custom_args)
+
+ @property
+ def send_at(self):
+ """The global SendAt object
+
+ :rtype: SendAt
+ """
+ return self._send_at
+
+ @send_at.setter
+ def send_at(self, value):
+ """A unix timestamp specifying when your email should
+ be delivered.
+
+ :param value: A unix timestamp specifying when your email should
+ be delivered.
+ :type value: SendAt, int
+ """
+ if isinstance(value, SendAt):
+ if value.personalization is not None:
+ try:
+ personalization = \
+ self._personalizations[value.personalization]
+ has_internal_personalization = True
+ except IndexError:
+ personalization = Personalization()
+ has_internal_personalization = False
+ personalization.send_at = value.send_at
+
+ if not has_internal_personalization:
+ self.add_personalization(
+ personalization, index=value.personalization)
+ else:
+ self._send_at = value
+ else:
+ self._send_at = SendAt(value)
+
+ @property
+ def dynamic_template_data(self):
+ pass
+
+ @dynamic_template_data.setter
+ def dynamic_template_data(self, value):
+ """Data for a transactional template
+
+ :param value: Data for a transactional template
+ :type value: DynamicTemplateData, a JSON-serializable structure
+ """
+ if not isinstance(value, DynamicTemplateData):
+ value = DynamicTemplateData(value)
+ try:
+ personalization = self._personalizations[value.personalization]
+ has_internal_personalization = True
+ except IndexError:
+ personalization = Personalization()
+ has_internal_personalization = False
+ personalization.dynamic_template_data = value.dynamic_template_data
+
+ if not has_internal_personalization:
+ self.add_personalization(
+ personalization, index=value.personalization)
+
+ @property
+ def from_email(self):
+ """The email address of the sender
+
+ :rtype: From
+ """
+ return self._from_email
+
+ @from_email.setter
+ def from_email(self, value):
+ """The email address of the sender
+
+ :param value: The email address of the sender
+ :type value: From, str, tuple
+ """
+ if isinstance(value, str):
+ value = From(value, None)
+ if isinstance(value, tuple):
+ value = From(value[0], value[1])
+ self._from_email = value
+
+ @property
+ def reply_to(self):
+ """The reply to email address
+
+ :rtype: ReplyTo
+ """
+ return self._reply_to
+
+ @reply_to.setter
+ def reply_to(self, value):
+ """The reply to email address
+
+ :param value: The reply to email address
+ :type value: ReplyTo, str, tuple
+ """
+ if isinstance(value, str):
+ value = ReplyTo(value, None)
+ if isinstance(value, tuple):
+ value = ReplyTo(value[0], value[1])
+ self._reply_to = value
+
+ @property
+ def reply_to_list(self):
+ """A list of ReplyTo email addresses
+
+ :rtype: list(ReplyTo), tuple
+ """
+ return self._reply_to_list
+
+ @reply_to_list.setter
+ def reply_to_list(self, value):
+ """A list of ReplyTo email addresses
+
+ :param value: A list of ReplyTo email addresses
+ :type value: list(ReplyTo), tuple
+ """
+ if isinstance(value, list):
+ for reply in value:
+ if isinstance(reply, ReplyTo):
+ if not isinstance(reply.email, str):
+ raise ValueError('You must provide an email for each entry in a reply_to_list')
+ else:
+ raise ValueError(
+ 'Please use a list of ReplyTos for a reply_to_list.'
+ )
+ self._reply_to_list = value
+
+ @property
+ def contents(self):
+ """The contents of the email
+
+ :rtype: list(Content)
+ """
+ return self._contents
+
+ @property
+ def content(self):
+ pass
+
+ @content.setter
+ def content(self, contents):
+ """The content(s) of the email
+
+ :param contents: The content(s) of the email
+ :type contents: Content, list(Content)
+ """
+ if isinstance(contents, list):
+ for c in contents:
+ self.add_content(c)
+ else:
+ self.add_content(contents)
+
+ def add_content(self, content, mime_type=None):
+ """Add content to the email
+
+ :param contents: Content to be added to the email
+ :type contents: Content
+ :param mime_type: Override the mime type
+ :type mime_type: MimeType, str
+ """
+ if isinstance(content, str):
+ content = Content(mime_type, content)
+ # Content of mime type text/plain must always come first, followed by text/x-amp-html and then text/html
+ if content.mime_type == MimeType.text:
+ self._contents = self._ensure_insert(content, self._contents)
+ elif content.mime_type == MimeType.amp:
+ if self._contents:
+ for _content in self._contents:
+ # this is written in the context that plain text content will always come earlier than the html content
+ if _content.mime_type == MimeType.text:
+ index = 1
+ break
+ elif _content.mime_type == MimeType.html:
+ index = 0
+ break
+ else:
+ index = 0
+ self._contents = self._ensure_append(
+ content, self._contents, index=index)
+ else:
+ if self._contents:
+ index = len(self._contents)
+ else:
+ index = 0
+ self._contents = self._ensure_append(
+ content, self._contents, index=index)
+
+ @property
+ def attachments(self):
+ """The attachments to this email
+
+ :rtype: list(Attachment)
+ """
+ return self._attachments
+
+ @property
+ def attachment(self):
+ pass
+
+ @attachment.setter
+ def attachment(self, attachment):
+ """Add attachment(s) to this email
+
+ :param attachment: Add attachment(s) to this email
+ :type attachment: Attachment, list(Attachment)
+ """
+ if isinstance(attachment, list):
+ for a in attachment:
+ self.add_attachment(a)
+ else:
+ self.add_attachment(attachment)
+
+ def add_attachment(self, attachment):
+ """Add an attachment to this email
+
+ :param attachment: Add an attachment to this email
+ :type attachment: Attachment
+ """
+ self._attachments = self._ensure_append(attachment, self._attachments)
+
+ @property
+ def template_id(self):
+ """The transactional template id for this email
+
+ :rtype: TemplateId
+ """
+ return self._template_id
+
+ @template_id.setter
+ def template_id(self, value):
+ """The transactional template id for this email
+
+ :param value: The transactional template id for this email
+ :type value: TemplateId
+ """
+ if isinstance(value, TemplateId):
+ self._template_id = value
+ else:
+ self._template_id = TemplateId(value)
+
+ @property
+ def sections(self):
+ """The block sections of code to be used as substitutions
+
+ :rtype: Section
+ """
+ return self._sections
+
+ @property
+ def section(self):
+ pass
+
+ @section.setter
+ def section(self, section):
+ """The block sections of code to be used as substitutions
+
+ :rtype: Section, list(Section)
+ """
+ if isinstance(section, list):
+ for h in section:
+ self.add_section(h)
+ else:
+ self.add_section(section)
+
+ def add_section(self, section):
+ """A block section of code to be used as substitutions
+
+ :param section: A block section of code to be used as substitutions
+ :type section: Section
+ """
+ self._sections = self._ensure_append(section, self._sections)
+
+ @property
+ def categories(self):
+ """The categories assigned to this message
+
+ :rtype: list(Category)
+ """
+ return self._categories
+
+ @property
+ def category(self):
+ pass
+
+ @category.setter
+ def category(self, categories):
+ """Add categories assigned to this message
+
+ :rtype: list(Category)
+ """
+ if isinstance(categories, list):
+ for c in categories:
+ self.add_category(c)
+ else:
+ self.add_category(categories)
+
+ def add_category(self, category):
+ """Add a category assigned to this message
+
+ :rtype: Category
+ """
+ self._categories = self._ensure_append(category, self._categories)
+
+ @property
+ def batch_id(self):
+ """The batch id for this email
+
+ :rtype: BatchId
+ """
+ return self._batch_id
+
+ @batch_id.setter
+ def batch_id(self, value):
+ """The batch id for this email
+
+ :param value: The batch id for this email
+ :type value: BatchId
+ """
+ self._batch_id = value
+
+ @property
+ def asm(self):
+ """An object specifying unsubscribe behavior.
+
+ :rtype: Asm
+ """
+ return self._asm
+
+ @asm.setter
+ def asm(self, value):
+ """An object specifying unsubscribe behavior.
+
+ :param value: An object specifying unsubscribe behavior.
+ :type value: Asm
+ """
+ self._asm = value
+
+ @property
+ def ip_pool_name(self):
+ """The IP Pool that you would like to send this email from
+
+ :rtype: IpPoolName
+ """
+ return self._ip_pool_name
+
+ @ip_pool_name.setter
+ def ip_pool_name(self, value):
+ """The IP Pool that you would like to send this email from
+
+ :paran value: The IP Pool that you would like to send this email from
+ :type value: IpPoolName
+ """
+ self._ip_pool_name = value
+
+ @property
+ def mail_settings(self):
+ """The mail settings for this email
+
+ :rtype: MailSettings
+ """
+ return self._mail_settings
+
+ @mail_settings.setter
+ def mail_settings(self, value):
+ """The mail settings for this email
+
+ :param value: The mail settings for this email
+ :type value: MailSettings
+ """
+ self._mail_settings = value
+
+ @property
+ def tracking_settings(self):
+ """The tracking settings for this email
+
+ :rtype: TrackingSettings
+ """
+ return self._tracking_settings
+
+ @tracking_settings.setter
+ def tracking_settings(self, value):
+ """The tracking settings for this email
+
+ :param value: The tracking settings for this email
+ :type value: TrackingSettings
+ """
+ self._tracking_settings = value
+
+ def get(self):
+ """
+ Get a JSON-ready representation of this Mail object.
+
+ :returns: This Mail object, ready for use in a request body.
+ :rtype: dict
+ """
+ mail = {
+ 'from': self._get_or_none(self.from_email),
+ 'subject': self._get_or_none(self.subject),
+ 'personalizations': [p.get() for p in self.personalizations or []],
+ 'content': [c.get() for c in self.contents or []],
+ 'attachments': [a.get() for a in self.attachments or []],
+ 'template_id': self._get_or_none(self.template_id),
+ 'sections': self._flatten_dicts(self.sections),
+ 'headers': self._flatten_dicts(self.headers),
+ 'categories': [c.get() for c in self.categories or []],
+ 'custom_args': self._flatten_dicts(self.custom_args),
+ 'send_at': self._get_or_none(self.send_at),
+ 'batch_id': self._get_or_none(self.batch_id),
+ 'asm': self._get_or_none(self.asm),
+ 'ip_pool_name': self._get_or_none(self.ip_pool_name),
+ 'mail_settings': self._get_or_none(self.mail_settings),
+ 'tracking_settings': self._get_or_none(self.tracking_settings),
+ 'reply_to': self._get_or_none(self.reply_to),
+ 'reply_to_list': [r.get() for r in self.reply_to_list or []],
+ }
+
+ 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_emails=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