Last updated:
0 purchases
mailbits 0.2.1
GitHub
| PyPI
| Issues
| Changelog
mailbits provides a small assortment of functions for working with the
Python standard library’s Message/EmailMessage, Address, and
Group types, as well as a couple other features. It can parse & reassemble
Content-Type strings, convert instances of the old Message class to the new
EmailMessage, convert Message & EmailMessage instances into
structured dicts, parse addresses, format address lists, and extract
recipients’ raw e-mail addresses from an EmailMessage.
Installation
mailbits requires Python 3.6 or higher. Just use pip for Python 3 (You have pip, right?) to install it:
python3 -m pip install mailbits
API
ContentType
The ContentType class provides a representation of a parsed Content-Type
header value. Parse Content-Type strings with the parse() classmethod,
inspect the parts via the content_type, maintype, subtype, and
params attributes (the last three of which can be mutated), convert back to
a string with str(), and convert to ASCII bytes using encoded words for
non-ASCII with bytes().
>>> from mailbits import ContentType
>>> ct = ContentType.parse("text/plain; charset=utf-8; name*=utf-8''r%C3%A9sum%C3%A9.txt")
>>> ct
ContentType(maintype='text', subtype='plain', params={'charset': 'utf-8', 'name': 'résumé.txt'})
>>> ct.content_type
'text/plain'
>>> str(ct)
'text/plain; charset="utf-8"; name="résumé.txt"'
>>> bytes(ct)
b'text/plain; charset="utf-8"; name*=utf-8\'\'r%C3%A9sum%C3%A9.txt'
email2dict()
class MessageDict(TypedDict):
unixfrom: Optional[str]
headers: Dict[str, Any]
preamble: Optional[str]
content: Any
epilogue: Optional[str]
mailbits.email2dict(msg: email.message.Message, include_all: bool = False) -> MessageDict
Convert a Message object to a dict. All encoded text & bytes are
decoded into their natural values.
Need to examine a Message but find the builtin Python API too fiddly? Need
to check that a Message has the content & structure you expect? Need to
compare two Message instances for equality? Need to pretty-print the
structure of a Message? Then email2dict() has your back.
By default, any information specific to how the message is encoded (Content-Type
parameters, Content-Transfer-Encoding, etc.) is not reported, as the focus is
on the actual content rather than the choices made in representing it. To
include this information anyway, set include_all to True.
The output structure has the following fields:
unixfrom
The “From “ line marking the start of the message in a mbox, if any
headers
A dict mapping lowercased header field names to values. The following
headers have special representations:
subject
A single string
from, to, cc, bcc, resent-from, resent-to, resent-cc, resent-bcc, reply-to
A list of groups and/or addresses. Addresses are represented as
dicts with two string fields: display_name (an empty string if
not given) and address. Groups are represented as dicts with
a group field giving the name of the group and an addresses
field giving a list of addresses in the group.
message-id
A single string
content-type
A dict containing a content_type field (a string of the form
maintype/subtype, e.g., "text/plain") and a params field (a
dict of string keys & values). The charset and boundary
parameters are discarded unless include_all is True.
date
A datetime.datetime instance
orig-date
A datetime.datetime instance
resent-date
A list of datetime.datetime instances
sender
A single address dict
resent-sender
A list of address dicts
content-disposition
A dict containing a disposition field (value either
"inline" or "attachment") and a params field (a dict of
string keys & values)
content-transfer-encoding
A single string. This header is discarded unless include_all is
True.
mime-version
A single string. This header is discarded unless include_all is
True.
All other headers are represented as lists of strings.
preamble
The message’s preamble
content
If the message is multipart, this is a list of message dicts,
structured the same way as the top-level dict. If the message’s
Content-Type is message/rfc822 or message/external-body, this is a
single message dict. If the message’s Content-Type is text/*, this
is a str giving the contents of the message. Otherwise, it is a
bytes giving the contents of the message.
epilogue
The message’s epilogue
An example: The email examples page in the Python docs includes an
example of constructing an HTML e-mail with an alternative plain text version
(It’s the one with the subject “Ayons asperges pour le déjeuner”). Passing the
resulting EmailMessage object to email2dict() produces the following
output structure:
{
"unixfrom": None,
"headers": {
"subject": "Ayons asperges pour le déjeuner",
"from": [
{
"display_name": "Pepé Le Pew",
"address": "[email protected]",
},
],
"to": [
{
"display_name": "Penelope Pussycat",
"address": "[email protected]",
},
{
"display_name": "Fabrette Pussycat",
"address": "[email protected]",
},
],
"content-type": {
"content_type": "multipart/alternative",
"params": {},
},
},
"preamble": None,
"content": [
{
"unixfrom": None,
"headers": {
"content-type": {
"content_type": "text/plain",
"params": {},
},
},
"preamble": None,
"content": (
"Salut!\n"
"\n"
"Cela ressemble à un excellent recipie[1] déjeuner.\n"
"\n"
"[1] http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718\n"
"\n"
"--Pepé\n"
),
"epilogue": None,
},
{
"unixfrom": None,
"headers": {
"content-type": {
"content_type": "multipart/related",
"params": {},
},
},
"preamble": None,
"content": [
{
"unixfrom": None,
"headers": {
"content-type": {
"content_type": "text/html",
"params": {},
},
},
"preamble": None,
"content": (
"<html>\n"
" <head></head>\n"
" <body>\n"
" <p>Salut!</p>\n"
" <p>Cela ressemble à un excellent\n"
" <a href=\"http://www.yummly.com/recipe/Roasted-Asparagus-"
"Epicurious-203718\">\n"
" recipie\n"
" </a> déjeuner.\n"
" </p>\n"
" <img src=\"cid:RANDOM_MESSAGE_ID\" />\n"
" </body>\n"
"</html>\n"
),
"epilogue": None,
},
{
"unixfrom": None,
"headers": {
"content-type": {
"content_type": "image/png",
"params": {},
},
"content-disposition": {
"disposition": "inline",
"params": {},
},
"content-id": ["<RANDOM_MESSAGE_ID>"],
},
"preamble": None,
"content": b'IMAGE BLOB',
"epilogue": None,
},
],
"epilogue": None,
},
],
"epilogue": None,
}
format_addresses()
mailbits.format_addresses(addresses: Iterable[Union[str, Address, Group]], encode: bool = False) -> str
Convert an iterable of e-mail address strings (of the form
“[email protected]”, without angle brackets or a display name),
email.headerregistry.Address objects, and/or email.headerregistry.Group
objects into a formatted string. If encode is False (the default),
non-ASCII characters are left as-is. If it is True, non-ASCII display
names are converted into RFC 2047 encoded words, and non-ASCII domain names
are encoded using Punycode.
message2email()
mailbits.message2email(msg: email.message.Message) -> email.message.EmailMessage
Convert an instance of the old Message class (or one of its subclasses,
like a mailbox message class) to an instance of the new EmailMessage
class with the default policy. If msg is already an EmailMessage,
it is returned unchanged.
parse_address()
mailbits.parse_address(s: str) -> email.headerregistry.Address
Parse a single e-mail address — either a raw address like “[email protected]”
or a combined display name & address like “Fabian Oh <[email protected]>”
into an Address object.
parse_addresses()
mailbits.parse_addresses(s: Union[str, email.headerregistry.AddressHeader]) \
-> List[Union[email.headerregistry.Address, email.headerregistry.Group]]
Parse a formatted list of e-mail addresses or the contents of an
EmailMessage’s “To”, “CC”, “BCC”, etc. header into a list of Address
and/or Group objects.
recipient_addresses()
mailbits.recipient_addresses(msg: email.message.EmailMessage) -> List[str]
Return a sorted list of all of the distinct e-mail addresses (not including
display names) in an EmailMessage’s combined “To”, “CC”, and “BCC” headers.
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.