API

Postman Object

class mailthon.postman.Postman(host, port, middlewares=(), options=None)

Encapsulates a connection to a server and knows how to send MIME emails over a certain transport. When subclassing, change the transport and response_cls class variables to tweak the transport used and the response class, respectively.

Parameters:
  • host – The address to a server.
  • port – Port to connect to.
  • middlewares – An iterable of middleware that will be used by the Postman.
  • options – Dictionary of options to be passed to the underlying transport.
transport

The transport class to be used. This defaults to the smtplib.SMTP class, but can be any callable that accepts a host, port, and the additional arguments specified in the options parameter. The recommended way to change this is via subclassing:

class HTTPPostman(Postman):
    transport = HTTPMailingProtocol

Although you can change it during runtime for special purposes such as testing. The transport class must also support the ehlo, noop, quit, and sendmail methods. For reference:

response_cls

The response class to be used. Defaults to the SendmailResponse class. It must be a callable which has the same type signature, and is recommended to be changed only by subclasses:

class HTTPPostman(Postman):
    response_cls = MyResponse

It will be called with the response returned by the noop() method, or the noop method of your own transport class.

connection(*args, **kwds)

A context manager that returns a connection to the server using some transport, defaulting to SMTP. The transport will be called with the server address, port, and options that have been passed to the constructor, in that order.

deliver(conn, envelope)

Deliver an envelope using a given connection conn, and return the response object. Does not close the connection.

send(envelope)

Sends an envelope and return a response object.

use(middleware)

Use a certain callable middleware, i.e. append it to the list of middlewares, and return it so it can be used as a decorator. Note that the middleware is added to the end of the middlewares list, so it will be called last.

Envelope Object

class mailthon.envelope.Envelope(headers, enclosure, mail_from=None)

Encapsulates the concept of an Envelope- there can be multiple stamps (headers) and multiple “things” inside the enclosure.

Parameters:
  • headers – An iterable/mapping of headers.
  • enclosure – A list of enclosure objects.
mail_from

Dictates the sender argument being passed to the SMTP.sendmail method. This is different from the sender property as it is the real sender, but the sender property is merely what appears on the email. If it is not set, the real sender is then inferred from the headers.

mime()

Returns a mime object. Internally this generates a MIMEMultipart object, attaches the enclosures, then prepares it using the internal headers object.

receivers

Returns a list of receiver addresses.

sender

Returns the sender of the envelope, obtained from the headers.

string()

Returns the MIME object as a string- i.e., calls the as_string method of the generated MIME object.

Enclosure Objects

class mailthon.enclosure.Enclosure(headers=())

Base class for Enclosure objects to inherit from. An enclosure is a part of the enclosure in a real envelope- it contains part of the content to be sent.

Parameters:headers – Iterable of headers to include, stored in an RFC-compliant Headers mapping internally under the headers attribute.
headers

A Header instance containing all of the headers. Note that when the enclosure objects are prepared (i.e. the mime() method is called), this headers attribute has precendence over other headers already set in the mime_object() method. For example:

e = EnclosureSubclass(
    mimetype='text/plain',
    headers={
        'Content-Type': 'text/html',
    })
mime = e.mime()
assert mime['Content-Type'] == 'text/html'

This is to ensure that the user ultimately has control over which headers are set in the final, prepared MIME object.

content

Anything the the Enclosure object contains. For example for PlainText enclosures this is usually a Unicode or bytes string. There is no restriction on what kind of object the content attribute may contain, but most of the time assume it is a string unless absolutely necessary, e.g. for some performance/memory-usage tweaks.

On the Enclosure base class this defaults to None.

mime()

Returns the finalised mime object, after applying the internal headers. Usually this is not to be overriden.

mime_object()

To be overriden. Returns the generated MIME object, without applying the internal headers.

class mailthon.enclosure.PlainText(content, encoding='utf-8', **kwargs)

Enclosure that has a text/plain mimetype.

Parameters:
  • content – Unicode or bytes string.
  • encoding – Encoding used to serialize the content or the encoding of the content.
  • headers – Optional headers.
class mailthon.enclosure.HTML(content, encoding='utf-8', **kwargs)

Subclass of PlainText with a text/html mimetype.

class mailthon.enclosure.Binary(content, mimetype, encoding=None, encoder=<function encode_base64>, **kwargs)

An Enclosure subclass for binary content. If the content is HTML or any kind of plain-text then the HTML or PlainText Enclosures are receommended since they have a simpler interface.

Parameters:
  • content – A bytes string.
  • mimetype – Mimetype of the content.
  • encoding – Optional encoding of the content.
  • encoder – An optional encoder function.
  • headers – Optional headers.
class mailthon.enclosure.Attachment(path, headers=())

Binary subclass for easier file attachments. The advantage over directly using the Binary class is that the Content-Disposition header is automatically set.

Parameters:
  • path – Absolute/Relative path to the file.
  • headers – Optional headers.
content

Lazily returns the bytes contents of the file.

Response Objects

class mailthon.response.Response(pair)

Encapsulates a (status_code, message) tuple returned by a server when the NOOP command is called.

Parameters:pair – A (status_code, message) pair.
status_code

The integer status code returned by the server. You can look up what they mean in the SMTP reply codes page.

message

The accompanying message returned by the server, as an undecoded bytes object. The message usually differs on a per-server basis.

ok

Tells whether the Response object is ok- that everything went well. Returns true if the status code is 250, false otherwise.

class mailthon.response.SendmailResponse(pair, rejected)

Encapsulates a (status_code, message) tuple as well as a mapping of email-address to (status_code, message) tuples that can be attained by the NOOP and the SENDMAIL command.

Parameters:
  • pair – The response pair.
  • rejected – Dictionary of rejected addresses to status-code message pairs.
rejected

A dictionary of rejected addresses to Response objects.

ok

Returns True only if no addresses were rejected and if the status code is 250.

Middlewares

class mailthon.middleware.Middleware

Base class for middlewares. Middlewares are encouraged to subclass from this class for extensibility reasons.

__call__(connection)

To be overriden by subclasses. This method is called by the Postman class when a connection to the server is established with the transport instance, e.g. an smtplib.SMTP object.

class mailthon.middleware.Auth(username, password)

Middleware implementing authentication via LOGIN. Most of the time this middleware needs to be placed after TLS.

Parameters:
  • username – Username to login with.
  • password – Password of the user.
class mailthon.middleware.TLS(force=False)

Middleware implementing TLS for SMTP connections. By default this is not forced- TLS is only used if STARTTLS is available. If the force parameter is set to True, it will not query the server for TLS features before upgrading to TLS.

Helper Functions

mailthon.helpers.stringify_address(addr, encoding='utf-8')

Given an email address addr, try to encode it with ASCII. If it’s not possible, encode the local-part with the encoding and the domain with IDNA.

The result is a unicode string with the domain encoded as idna.

mailthon.helpers.guess(filename, fallback='application/octet-stream')

Using the mimetypes library, guess the mimetype and encoding for a given filename. If the mimetype cannot be guessed, fallback is assumed instead.

Parameters:
  • filename – Filename- can be absolute path.
  • fallback – A fallback mimetype.
mailthon.helpers.format_addresses(addrs)

Given an iterable of addresses or name-address tuples addrs, return a header value that joins all of them together with a space and a comma.

mailthon.helpers.UnicodeDict(values=(), encoding='utf-8')

A dictionary that handles unicode values magically - that is, byte-values are automatically decoded. Accepts a dict or iterable values.

Headers

class mailthon.headers.Headers(values=(), encoding='utf-8')

RFC 2822 compliant subclass of the UnicodeDict. The semantics of the dictionary is different from that of the standard library MIME object- only the latest header is preserved instead of preserving all headers. This makes header lookup deterministic and sane.

prepare(mime)

Prepares a MIME object by applying the headers to the mime object. Ignores any Bcc or Resent-Bcc headers.

receivers

Returns a list of receivers, obtained from the To, Cc, and Bcc headers, respecting the Resent-* headers if the email was resent.

resent

Whether the email was resent, i.e. whether the Resent-Date header was set.

sender

Returns the sender, respecting the Resent-* headers. In any case, prefer Sender over From, meaning that if Sender is present then From is ignored, as per the RFC.

Header Functions

The following functions are the recommended way to set the commonly used headers, instead of providing the string values yourself. They are generator functions and can be used like so:

>>> from mailthon.headers import sender
>>> dict([sender('sender')])
{'Sender': 'sender'}
mailthon.headers.sender(address)

Generates a Sender header with a given text. text can be both a tuple or a string.

mailthon.headers.to(*addrs)

Generates a To header with the given addrs, where addrs can be made of Name <address> or address strings, or a mix of both.

mailthon.headers.cc(*addrs)

Similar to to function. Generates a Cc header.

mailthon.headers.bcc(*addrs)

Generates a Bcc header. This is safe when using the mailthon Headers implementation because the Bcc headers will not be included in the MIME object.

mailthon.headers.message_id(string=None, idstring=None)

Generates a Message-ID header, by yielding a given string if specified, else an RFC compliant message-id generated by make_msgid and strengthened by an optional idstring.

mailthon.headers.date(time=None)

Generates a Date header. Yields the time as the key if specified, else returns an RFC compliant date generated by formatdate.