API¶
The compose()
Function¶
-
eletter.
compose
(*, subject: str, to: Iterable[Union[str, email.headerregistry.Address, email.headerregistry.Group]], from_: Optional[Union[str, email.headerregistry.Address, email.headerregistry.Group, Iterable[Union[str, email.headerregistry.Address, email.headerregistry.Group]]]] = None, text: Optional[str] = None, html: Optional[str] = None, cc: Optional[Iterable[Union[str, email.headerregistry.Address, email.headerregistry.Group]]] = None, bcc: Optional[Iterable[Union[str, email.headerregistry.Address, email.headerregistry.Group]]] = None, reply_to: Optional[Union[str, email.headerregistry.Address, email.headerregistry.Group, Iterable[Union[str, email.headerregistry.Address, email.headerregistry.Group]]]] = None, sender: Optional[Union[str, email.headerregistry.Address]] = None, date: Optional[datetime.datetime] = None, headers: Optional[Mapping[str, Union[str, Iterable[str]]]] = None, attachments: Optional[Iterable[eletter.classes.Attachment]] = None) → email.message.EmailMessage[source]¶ Construct an
EmailMessage
instance from a subject, From address, To addresses, and a plain text and/or HTML body, optionally accompanied by attachments and other headers.All parameters other than
subject
,to
, and at least one oftext
andhtml
are optional.- Parameters
subject (str) – The e-mail’s Subject line
to (iterable of addresses) – The e-mail’s To line
from (address or iterable of addresses) – The e-mail’s From line. Note that this argument is spelled with an underscore, as “
from
” is a keyword in Python.text (str) – The contents of a text/plain body for the e-mail. At least one of
text
andhtml
must be specified.html (str) – The contents of a text/html body for the e-mail. At least one of
text
andhtml
must be specified.cc (iterable of addresses) – The e-mail’s CC line
bcc (iterable of addresses) – The e-mail’s BCC line
reply_to (address or iterable of addresses) – The e-mail’s Reply-To line
sender (address) – The e-mail’s Sender line. The address must be a string or
Address
, not aGroup
.date (datetime) – The e-mail’s Date line
attachments (iterable of attachments) – A collection of attachments to append to the e-mail
headers (mapping) – A collection of additional headers to add to the e-mail. A header value may be either a single string or an iterable of strings to add multiple headers with the same name. If you wish to set an otherwise-unsupported address header like Resent-From to a list of addresses, use the
format_addresses()
function to first convert the addresses to a string.
- Return type
- Raises
ValueError – if neither
text
norhtml
is set
Addresses¶
Addresses in eletter
can be specified in three ways:
As an
"address@domain.com"
string giving just a bare e-mail addressAs an
eletter.Address("Display Name", "address@domain.com")
instance pairing a person’s name with an e-mail addressAs an
eletter.Group("Group Name", iterable_of_addresses)
instance specifying a group of addresses (strings orAddress
instances)
Note
eletter.Address
and eletter.Group
are actually just subclasses of
Address
and Group
from
email.headerregistry
with slightly more convenient constructors. You can
also use the standard library types directly, if you want to.
-
class
eletter.
Address
(display_name: str, address: str)[source]¶ A combination of a person’s name and their e-mail address
-
class
eletter.
Group
(display_name: str, addresses: Iterable[Union[str, email.headerregistry.Address]])[source]¶ An e-mail address group
MailItem
Classes¶
-
class
eletter.
MailItem
[source]¶ Base class for all
eletter
message components-
compose
(*, subject: str, to: Iterable[Union[str, email.headerregistry.Address, email.headerregistry.Group]], from_: Optional[Union[str, email.headerregistry.Address, email.headerregistry.Group, Iterable[Union[str, email.headerregistry.Address, email.headerregistry.Group]]]] = None, cc: Optional[Iterable[Union[str, email.headerregistry.Address, email.headerregistry.Group]]] = None, bcc: Optional[Iterable[Union[str, email.headerregistry.Address, email.headerregistry.Group]]] = None, reply_to: Optional[Union[str, email.headerregistry.Address, email.headerregistry.Group, Iterable[Union[str, email.headerregistry.Address, email.headerregistry.Group]]]] = None, sender: Optional[Union[str, email.headerregistry.Address]] = None, date: Optional[datetime.datetime] = None, headers: Optional[Mapping[str, Union[str, Iterable[str]]]] = None) → email.message.EmailMessage[source]¶ Convert the
MailItem
into anEmailMessage
with the item’s contents as the payload and with the given subject, From address, To addresses, and optional other headers.All parameters other than
subject
andto
are optional.- Parameters
subject (str) – The e-mail’s Subject line
to (iterable of addresses) – The e-mail’s To line
from (address or iterable of addresses) – The e-mail’s From line. Note that this argument is spelled with an underscore, as “
from
” is a keyword in Python.cc (iterable of addresses) – The e-mail’s CC line
bcc (iterable of addresses) – The e-mail’s BCC line
reply_to (address or iterable of addresses) – The e-mail’s Reply-To line
sender (address) – The e-mail’s Sender line. The address must be a string or
Address
, not aGroup
.date (datetime) – The e-mail’s Date line
headers (mapping) – A collection of additional headers to add to the e-mail. A header value may be either a single string or an iterable of strings to add multiple headers with the same name. If you wish to set an otherwise-unsupported address header like Resent-From to a list of addresses, use the
format_addresses()
function to first convert the addresses to a string.
- Return type
-
Attachments¶
-
class
eletter.
BytesAttachment
(content: bytes, filename: str, *, content_id: Optional[str] = None, content_type: str = NOTHING, inline: bool = False)[source]¶ A binary e-mail attachment.
content_type
defaults to"application/octet-stream"
.-
classmethod
from_file
(path: Union[bytes, str, os.PathLike[bytes], os.PathLike[str]], content_type: Optional[str] = None, inline: bool = False, content_id: Optional[str] = None) → BytesAttachment[source]¶ Construct a
BytesAttachment
from the contents of the file atpath
. The filename of the attachment will be set to the basename ofpath
. Ifcontent_type
isNone
, the Content-Type is guessed based onpath
’s file extension.
-
classmethod
-
class
eletter.
EmailAttachment
(content: email.message.EmailMessage, filename: str, *, content_id: Optional[str] = None, inline: bool = False)[source]¶ A message/rfc822 e-mail attachment
-
content
: email.message.EmailMessage¶ The body of the attachment
-
classmethod
from_file
(path: Union[bytes, str, os.PathLike[bytes], os.PathLike[str]], inline: bool = False, content_id: Optional[str] = None) → EmailAttachment[source]¶ Construct an
EmailAttachment
from the contents of the file atpath
. The filename of the attachment will be set to the basename ofpath
.
-
-
class
eletter.
TextAttachment
(content: str, filename: str, *, content_id: Optional[str] = None, content_type: str = NOTHING, inline: bool = False)[source]¶ A textual e-mail attachment.
content_type
defaults to"text/plain"
and must have a maintype of text.-
classmethod
from_file
(path: Union[bytes, str, os.PathLike[bytes], os.PathLike[str]], content_type: Optional[str] = None, encoding: Optional[str] = None, errors: Optional[str] = None, inline: bool = False, content_id: Optional[str] = None) → TextAttachment[source]¶ Construct a
TextAttachment
from the contents of the file atpath
. The filename of the attachment will be set to the basename ofpath
. Ifcontent_type
isNone
, the Content-Type is guessed based onpath
’s file extension.encoding
anderrors
are used when opening the file and have no relation to the Content-Type.
-
classmethod
Body Classes¶
Multipart Classes¶
-
class
eletter.
Multipart
[source]¶ Base class for all multipart classes. All such classes are mutable sequences of
MailItem
s supporting the usual methods (construction from an iterable, subscription,append()
,pop()
, etc.).
-
class
eletter.
Alternative
(content=NOTHING, *, content_id: Optional[str] = None)[source]¶ A multipart/alternative e-mail payload. E-mails clients will display the resulting payload by choosing whichever part they support best.
An
Alternative
instance can be created by combining two or moreMailItem
s with the|
operator:text = TextBody("This is displayed on plain text clients.\n") html = HTMLBody("<p>This is displayed on graphical clients.<p>\n") alternative = text | html
Likewise, additional
MailItem
s can be added to anAlternative
instance with the|=
operator:# Same as above: alternative = Alternative() alternative |= TextBody("This is displayed on plain text clients.\n") alternative |= HTMLBody("<p>This is displayed on graphical clients.<p>\n")
Using
|
to combine aMailItem
with astr
automatically converts thestr
to aTextBody
:# Same as above: text = "This is displayed on plain text clients.\n" html = HTMLBody("<p>This is displayed on graphical clients.<p>\n") alternative = text | html assert alternative.contents == [ TextBody("This is displayed on plain text clients.\n"), HTMLBody("<p>This is displayed on graphical clients.<p>\n"), ]
When combining two
Alternative
instances with|
or|=
, the contents are “flattened”:# Same as above: txtalt = Alternative([ TextBody("This is displayed on plain text clients.\n") ]) htmlalt = Alternative([ HTMLBody("<p>This is displayed on graphical clients.<p>\n") ]) alternative = txtalt | htmlalt assert alternative.contents == [ TextBody("This is displayed on plain text clients.\n"), HTMLBody("<p>This is displayed on graphical clients.<p>\n"), ]
-
class
eletter.
Mixed
(content=NOTHING, *, content_id: Optional[str] = None)[source]¶ A multipart/mixed e-mail payload. E-mails clients will display the resulting payload one part after another, with attachments displayed inline if their
inline
attribute is set.A
Mixed
instance can be created by combining two or moreMailItem
s with the&
operator:text = TextBody("Look at the pretty kitty!\n") image = BytesAttachment.from_file("snuffles.jpeg", inline=True) sig = TextBody("Sincerely, Me\n") mixed = text & image & sig
Likewise, additional
MailItem
s can be added to aMixed
instance with the&=
operator:# Same as above: mixed = Mixed() mixed &= TextBody("Look at the pretty kitty!\n") mixed &= BytesAttachment.from_file("snuffles.jpeg", inline=True) mixed &= TextBody("Sincerely, Me\n")
Using
&
to combine aMailItem
with astr
automatically converts thestr
to aTextBody
:# Same as above: image = BytesAttachment.from_file("snuffles.jpeg", inline=True) mixed = "Look at the pretty kitty!\n" & image & "Sincerely, Me\n" assert mixed.contents == [ TextBody("Look at the pretty kitty!\n"), BytesAttachment.from_file("snuffles.jpeg", inline=True), TextBody("Sincerely, Me\n"), ]
When combining two
Mixed
instances with&
or&=
, the contents are “flattened”:part1 = Mixed() part1 &= TextBody("Look at the pretty kitty!\n") part1 &= BytesAttachment.from_file("snuffles.jpeg", inline=True) part2 = Mixed() part2 &= TextBody("Now look at this dog.\n") part2 &= BytesAttachment.from_file("rags.jpeg", inline=True) part2 &= TextBody("Which one is cuter?\n") mixed = part1 & part2 assert mixed.contents == [ TextBody("Look at the pretty kitty!\n"), BytesAttachment.from_file("snuffles.jpeg", inline=True), TextBody("Now look at this dog.\n"), BytesAttachment.from_file("rags.jpeg", inline=True), TextBody("Which one is cuter?\n"), ]
-
class
eletter.
Related
(content=NOTHING, start: Optional[str] = None, *, content_id: Optional[str] = None)[source]¶ A multipart/related e-mail payload. E-mail clients will display the part indicated by the
start
parameter, or the first part ifstart
is not set. This part may refer to other parts (e.g., images or CSS stylesheets) by their Content-ID headers, which can be generated usingemail.utils.make_msgid()
.Note
Content-ID headers begin & end with angle brackets (
<...>
), which need to be stripped off before including the ID in the starting part.A
Related
instance can be created by combining two or moreMailItem
s with the^
operator:from email.utils import make_msgid img_cid = make_msgid() html = HTMLBody( "<p>Look at the pretty kitty!</p>" f'<img src="cid:{img_cid[1:-1]}"/>" "<p>Isn't he <em>darling</em>?</p>" ) image = BytesAttachment.from_file("snuffles.jpeg", content_id=img_cid) related = html ^ image
Likewise, additional
MailItem
s can be added to aRelated
instance with the^=
operator:# Same as above: img_cid = make_msgid() related = Related() related ^= HTMLBody( "<p>Look at the pretty kitty!</p>" f'<img src="cid:{img_cid[1:-1]}"/>" "<p>Isn't he <em>darling</em>?</p>" ) related ^= BytesAttachment.from_file("snuffles.jpeg", content_id=img_cid)
Using
^
to combine aMailItem
with astr
automatically converts thestr
to aTextBody
, though this is generally not all that useful, as you’ll usually want to createRelated
instances fromHTMLBody
s instead.When combining two
Related
instances with^
or^=
, the contents are “flattened”:# Same as above: img_cid = make_msgid() htmlrel = Related([ HTMLBody( "<p>Look at the pretty kitty!</p>" f'<img src="cid:{img_cid[1:-1]}"/>" "<p>Isn't he <em>darling</em>?</p>" ) ]) imgrel = Related([ BytesAttachment.from_file("snuffles.jpeg", content_id=img_cid) ]) related = htmlrel ^ imgrel assert related.contents == [ HTMLBody( "<p>Look at the pretty kitty!</p>" f'<img src="cid:{img_cid[1:-1]}"/>" "<p>Isn't he <em>darling</em>?</p>" ), BytesAttachment.from_file("snuffles.jpeg", content_id=img_cid), ]
Utility Functions¶
-
eletter.
assemble_content_type
(maintype: str, subtype: str, **params: str) → str[source]¶ Construct a Content-Type string from a maintype, subtype, and some number of parameters
- Raises
ValueError – if
f"{maintype}/{subtype}"
is an invalid Content-Type
-
eletter.
format_addresses
(addresses: Iterable[Union[str, email.headerregistry.Address, email.headerregistry.Group]], encode: bool = False) → str[source]¶ Convert an iterable of e-mail address strings (of the form “
foo@example.com
”, without angle brackets or a display name),Address
objects, and/orGroup
objects into a formatted string. Ifencode
isFalse
(the default), non-ASCII characters are left as-is. If it isTrue
, non-ASCII display names are converted into RFC 2047 encoded words, and non-ASCII domain names are encoded using Punycode.
-
eletter.
reply_quote
(s: str, prefix: str = '> ') → str[source]¶ Quote a text following the de facto standard for replying to an e-mail; that is, prefix each line of the text with
"> "
(or a custom prefix), and if a line already starts with the prefix, omit any trailing whitespace from the newly-added prefix (so"> already quoted"
becomes">> already quoted"
).If the resulting string does not end with a newline, one is added. The empty string is treated as a single line.