Supportive¶
- .recipients(): Return set of all recipients –
To,Cc,Bcc- .recipients(clear=True): All
To,CcandBccrecipients are removed and theEnvelopeobject is returned.
- .recipients(clear=True): All
- attachments: Access the list of attachments.
- --attachments [NAME] Get the list of attachments or a contents of the one specified by
NAME - .attachments(name=None, inline=None)
- name (str): The name of the only desired attachment to be returned.
- inline (bool): Filter inline/enclosed attachments only.
- Attachment object has the attributes .name file name, .mimetype, .data raw data
- if casted to str/bytes, its raw .data are returned
- --attachments [NAME] Get the list of attachments or a contents of the one specified by
- .copy(): Return deep copy of the instance to be used independently.
factory = Envelope().cc("original@example.com").copy e1 = factory().to("to-1@example.com") e2 = factory().to("to-2@example.com").cc("additional@example.com") # print(e1.recipients()) # {'to-1@example.com', 'original@example.com'} print(e2.recipients()) # {'to-2@example.com', 'original@example.com', 'additional@example.com'} - Read message and subject by .message() and .subject()
- preview: Returns the string of the message or data as a human-readable text.
Ex: whilst we have to use quoted-printable (as seen in str), here the output will be plain text.
- --preview
- .preview()
-
check: Check all e-mail addresses and SMTP connection and return True/False if succeeded. Tries to find SPF, DKIM and DMARC DNS records depending on the From's domain and print them out.
- --check
- .check(check_mx=True, check_smtp=True)
check_mxE-mail addresses can be checked for MX record, not only for their format.check_smtpWe try to connect to the SMTP host.
* .as_message(): Generates an email.message.Message object.$ envelope --smtp localhost 25 --from me@example.com --check SPF found on the domain example.com: v=spf1 -all See: dig -t SPF example.com && dig -t TXT example.com DKIM found: ['v=DKIM1; g=*; k=rsa; p=...'] Could not spot DMARC. Trying to connect to the SMTP... Check succeeded.Note: due to a bug in a standard Python library https://github.com/python/cpython/issues/99533 and #19 you void GPG when you access the message this way wihle signing an attachment with a name longer than 34 chars. * load: Parse any attainable contents (including email.message.Message) like an EML file to build an Envelope object. It can decrypt the message and parse its (inline or enclosed) attachments.e = Envelope("hello").as_message() print(type(e), e.get_payload()) # <class 'email.message.EmailMessage'> hello\nNote that if you send this reconstructed message, you might not receive it due to Message-ID duplication — delete at least the
Message-IDheader prior to re-sending.(static) .load(message, *, path=None, key=None, cert=None, gnupg_home=None)
- message: Any attainable contents
- path: Path to the file, alternative to the
message - key, cert: Specify when decrypting an S/MIME message (may be bundled together to the
key) - gnupg_home: Path to the GNUPG_HOME or None if the environment default should be used.
In bash, blank
--subjector--messageflags display the respective value of the loaded message. Use --load FILE to load an EML file:$ envelope --load email.eml Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit MIME-Version: 1.0 Subject: testing message Message body $ envelope --load email.eml --subject testing messageContent may also be piped in, with
* smtp_quit(): As Envelope tends to re-use all the SMTP instances, you may want to quit them explicitly. Either call this method to the Envelope class to close all the cached connections or to an Envelope object to close only the connection it currently uses.enveloperun without any arguments:
Address¶
Any e-mail address encountered is internally converted to an Address(str) object that can be imported from the envelope package. You can safely access following str properties:
* .name – the real name
* .address – the e-mail address
* .host – its domain
* .user – the user name part of the e-mail
from envelope import Address
a = Address("John <person@example.com>")
a.name == "John", a.address == "person@example.com", a.host == "example.com", a.user == "person"
Empty object works too. For example, if the From header is not set, we get an empty Address object. Still it is safe to access its properties.
a = Envelope.load("Empty message").from_()
bool(a) is False, a.host == ""
Address() == Address("") == "", Address().address == ""
Method .casefold() returns casefolded Address object which is useful for comparing with strings whereas comparing with other Address object casefolds automatically
a = Address("John <person@example.com>")
c = a.casefold()
a is not c, a == c, a.name == "john", a.name != c.name
Method .is_valid(check_mx=False) returns boolean if the format is valid. When check_mx set to True, MX server is inquired too.
Since the Address is a subclass of str, you can safely join such objects.
", ".join([a, a]) # "John <person@example.com>, "John <person@example.com>"
a + " hello" # "John <person@example.com> hello"
Address objects are equal if their e-mail address are equal. (Their real names might differ.) Address object is equal to a string if the string contains its e-mail address or the whole representation.
Concerning to, cc, bcc and reply-to, multiple addresses may always be given in a string, delimited by comma (or semicolon). The .get(address:bool, name:bool) method may be called on an Address object to filter the desired information.
e = (Envelope()
.to("person1@example.com")
.to("person1@example.com, John <person2@example.com>")
.to(["person3@example.com"]))
[str(x) for x in e.to()] # ["person1@example.com", "John <person2@example.com>", "person3@example.com"]
[x.get(address=False) for x in e.to()] # ["", "John", ""]
[x.get(name=True) for x in e.to()] # ["person1@example.com", "John", "person3@example.com"]
# return an address if no name given
[x.get(address=True) for x in e.to()] # ["person1@example.com", "person2@example.com", "person3@example.com"]
# addresses only
For some exotic cases, Address tends to do the parsing job better than the underlying standard library (see the bug report from 2004).