API Reference¶
This section documents the public API of the python-emails library.
Message¶
The Message class is the main entry point for creating and sending emails.
- class Message(\*\*kwargs)¶
Create a new email message.
- Parameters:
html (str or None) – HTML body content (string or file-like object).
text (str or None) – Plain text body content (string or file-like object).
subject (str or None) – Email subject line. Supports template rendering.
mail_from (str or tuple or None) – Sender address. Accepts a string
"user@example.com"or a tuple("Display Name", "user@example.com").mail_to (str or tuple or list or None) – Recipient address(es). Accepts a string, tuple, or list of strings/tuples.
cc (str or tuple or list or None) – CC recipient(s). Same format as
mail_to.bcc (str or tuple or list or None) – BCC recipient(s). Same format as
mail_to.reply_to (str or tuple or list or None) – Reply-To address(es). Same format as
mail_to.headers (dict or None) – Custom email headers as a dictionary.
headers_encoding (str or None) – Encoding for email headers (default:
'ascii').attachments (list or None) – List of attachments (dicts or
BaseFileobjects).charset (str or None) – Message character set (default:
'utf-8').message_id (str or
MessageIDor bool or None) – Message-ID header value. Can be a string, aMessageIDinstance,Falseto omit, orNoneto auto-generate.date (str or datetime or float or bool or callable or None) – Date header value. Accepts a string,
datetime, float (timestamp),Falseto omit, or a callable that returns one of these types.
Example:
import emails msg = emails.Message( html="<p>Hello, World!</p>", subject="Test Email", mail_from=("Sender", "sender@example.com"), mail_to="recipient@example.com" )
Message Methods¶
- Message.send(to=None, set_mail_to=True, mail_from=None, set_mail_from=False, render=None, smtp_mail_options=None, smtp_rcpt_options=None, smtp=None)¶
Send the message via SMTP.
- Parameters:
to – Override recipient address(es).
set_mail_to – If
True, update the message’smail_towithto.mail_from – Override sender address.
set_mail_from – If
True, update the message’smail_from.render – Dictionary of template variables for rendering.
smtp_mail_options – SMTP MAIL command options.
smtp_rcpt_options – SMTP RCPT command options.
smtp – SMTP configuration. Either a dict with connection parameters (
host,port,ssl,tls,user,password,timeout) or anSMTPBackendinstance.
- Returns:
SMTPResponseorNone
Example:
response = msg.send( to="user@example.com", smtp={"host": "smtp.example.com", "port": 587, "tls": True, "user": "login", "password": "secret"} )
- Message.send_async(to=None, set_mail_to=True, mail_from=None, set_mail_from=False, render=None, smtp_mail_options=None, smtp_rcpt_options=None, smtp=None)¶
Send the message via SMTP asynchronously. Requires
aiosmtplib(install withpip install "emails[async]").Parameters are the same as
send(), exceptsmtpaccepts a dict or anAsyncSMTPBackendinstance.When
smtpis a dict, a temporaryAsyncSMTPBackendis created and closed after sending. When an existing backend is passed, the caller is responsible for closing it.- Returns:
SMTPResponseorNone
Example:
response = await msg.send_async( to="user@example.com", smtp={"host": "smtp.example.com", "port": 587, "tls": True, "user": "login", "password": "secret"} )
Using a shared backend for multiple sends:
from emails.backend.smtp.aio_backend import AsyncSMTPBackend async with AsyncSMTPBackend(host="smtp.example.com", port=587, tls=True, user="login", password="secret") as backend: for msg in messages: await msg.send_async(smtp=backend)
- Message.attach(\*\*kwargs)¶
Attach a file to the message. Sets
content_dispositionto'attachment'by default.- Parameters:
filename – Name of the attached file.
data – File content as bytes or a file-like object.
content_disposition –
'attachment'(default) or'inline'.mime_type – MIME type of the file. Auto-detected from filename if not specified.
Example:
msg.attach(filename="report.pdf", data=open("report.pdf", "rb")) msg.attach(filename="logo.png", data=img_data, content_disposition="inline")
- Message.render(\*\*kwargs)¶
Set template rendering data. Template variables are substituted when accessing
html_body,text_body, orsubject.- Parameters:
kwargs – Key-value pairs used as template context.
Example:
msg = emails.Message( html=emails.template.JinjaTemplate("<p>Hello {{ name }}</p>"), subject=emails.template.JinjaTemplate("Welcome, {{ name }}") ) msg.render(name="World")
- Message.as_string(message_cls=None)¶
Return the message as a string, including DKIM signature if configured.
- Parameters:
message_cls – Optional custom MIME message class.
- Returns:
Message as a string.
- Return type:
- Message.as_bytes(message_cls=None)¶
Return the message as bytes with CRLF line endings, including DKIM signature if configured.
- Parameters:
message_cls – Optional custom MIME message class.
- Returns:
Message as bytes.
- Return type:
- Message.as_message(message_cls=None)¶
Return the underlying MIME message object.
- Parameters:
message_cls – Optional custom MIME message class.
- Returns:
MIME message object.
- Message.transform(\*\*kwargs)¶
Apply HTML transformations to the message body. Loads and processes the HTML content through the transformer.
See the HTML Transformations section for available parameters.
- Message.dkim(key, domain, selector, ignore_sign_errors=False, \*\*kwargs)¶
Configure DKIM signing for the message. The signature is applied when the message is serialized via
as_string(),as_bytes(), orsend().This method is also available as
sign().- Parameters:
key – Private key for signing (PEM format). String, bytes, or file-like object.
domain – DKIM domain (e.g.,
"example.com").selector – DKIM selector (e.g.,
"default").ignore_sign_errors – If
True, suppress signing exceptions.
- Returns:
The message instance (for chaining).
- Return type:
Example:
msg.dkim(key=open("private.pem"), domain="example.com", selector="default")
Message Properties¶
- Message.html¶
Get or set the HTML body content.
- Message.text¶
Get or set the plain text body content.
- Message.html_body¶
The rendered HTML body (read-only). If templates are used, returns the rendered result; otherwise returns the raw HTML.
- Message.text_body¶
The rendered text body (read-only). If templates are used, returns the rendered result; otherwise returns the raw text.
- Message.mail_from¶
Get or set the sender address. Returns a
(name, email)tuple.
- Message.mail_to¶
Get or set the recipient address(es). Returns a list of
(name, email)tuples.
- Message.cc¶
Get or set CC recipient(s). Returns a list of
(name, email)tuples.
- Message.bcc¶
Get or set BCC recipient(s). Returns a list of
(name, email)tuples.
- Message.reply_to¶
Get or set Reply-To address(es). Returns a list of
(name, email)tuples.
- Message.subject¶
Get or set the email subject. Supports template rendering.
- Message.message_id¶
Get or set the Message-ID header value.
- Message.date¶
Get or set the Date header value.
- Message.charset¶
Get or set the message character set (default:
'utf-8').
- Message.headers_encoding¶
Get or set the encoding for email headers (default:
'ascii').
- Message.attachments¶
Access the attachment store (
MemoryFileStore). Lazily initialized.
- Message.render_data¶
Get or set the template rendering context dictionary.
- Message.transformer¶
Access the HTML transformer for custom image/link transformations. Lazily created on first access. See the HTML Transformations section for usage examples.
SMTPResponse¶
Returned by Message.send(). Contains information about the SMTP transaction.
- class SMTPResponse¶
- status_code¶
The SMTP status code from the last command (e.g.,
250for success).Noneif the transaction was not completed.
- status_text¶
The SMTP status text from the last command, as bytes.
- success¶
Trueif the message was sent successfully (status code is250and the transaction completed).
- error¶
The exception object if an error occurred, or
None.
- refused_recipients¶
A dictionary mapping refused recipient email addresses to
(code, message)tuples.
- last_command¶
The last SMTP command that was sent (e.g.,
'mail','rcpt','data').
Example:
response = msg.send(smtp={"host": "localhost"}) if response.success: print("Sent!") else: print(f"Failed: {response.status_code} {response.status_text}") if response.error: print(f"Error: {response.error}") if response.refused_recipients: print(f"Refused: {response.refused_recipients}")
AsyncSMTPBackend¶
For async sending via Message.send_async(). Requires aiosmtplib
(install with pip install "emails[async]").
- class emails.backend.smtp.aio_backend.AsyncSMTPBackend(ssl=False, fail_silently=True, mail_options=None, \*\*kwargs)¶
Manages an async SMTP connection. Supports
async withfor automatic cleanup.- Parameters:
host – SMTP server hostname.
port – SMTP server port.
ssl – Use implicit TLS (SMTPS).
tls – Use STARTTLS after connecting.
user – SMTP username for authentication.
password – SMTP password for authentication.
timeout – Connection timeout in seconds (default:
5).fail_silently – If
True(default), SMTP errors are captured in the response rather than raised.mail_options – Default SMTP MAIL command options.
- async sendmail(from_addr, to_addrs, msg, mail_options=None, rcpt_options=None)¶
Send a message. Automatically retries once on server disconnect.
- Returns:
SMTPResponseorNone
- async close()¶
Close the SMTP connection.
Example:
from emails.backend.smtp.aio_backend import AsyncSMTPBackend async with AsyncSMTPBackend(host="smtp.example.com", port=587, tls=True, user="me", password="secret") as backend: response = await backend.sendmail( from_addr="sender@example.com", to_addrs=["recipient@example.com"], msg=message )
Loaders¶
Loader functions create Message instances from various sources.
All loaders are available in the emails.loader module.
- emails.loader.from_html(html, text=None, base_url=None, message_params=None, local_loader=None, template_cls=None, message_cls=None, source_filename=None, requests_params=None, \*\*kwargs)¶
Create a message from an HTML string. Images and stylesheets referenced in the HTML can be automatically loaded and embedded.
- Parameters:
html – HTML content as a string.
text – Optional plain text alternative.
base_url – Base URL for resolving relative URLs in the HTML.
message_params – Additional parameters passed to the Message constructor.
local_loader – A loader instance for resolving local file references.
template_cls – Template class to use for the HTML body.
message_cls – Custom Message class to instantiate.
source_filename – Filename hint for the source HTML.
requests_params – Parameters passed to HTTP requests when fetching resources.
kwargs – Additional transformer options.
- Returns:
A
Messageinstance.
from_stringis an alias for this function.
- emails.loader.from_url(url, requests_params=None, \*\*kwargs)¶
Create a message by downloading an HTML page from a URL. Images and stylesheets are fetched and embedded.
- Parameters:
url – URL of the HTML page.
requests_params – Parameters passed to HTTP requests.
kwargs – Additional transformer options.
- Returns:
A
Messageinstance.
load_urlis an alias for this function.
- emails.loader.from_directory(directory, loader_cls=None, \*\*kwargs)¶
Create a message from a local directory. The directory should contain an HTML file and any referenced images or attachments.
- Parameters:
directory – Path to the directory.
loader_cls – Custom loader class.
kwargs – Additional options (
html_filename,text_filename,message_params).
- Returns:
A
Messageinstance.
- emails.loader.from_zip(zip_file, loader_cls=None, \*\*kwargs)¶
Create a message from a ZIP archive containing HTML and resources.
- Parameters:
zip_file – Path to ZIP file or a file-like object.
loader_cls – Custom loader class.
kwargs – Additional options (
html_filename,text_filename,message_params).
- Returns:
A
Messageinstance.
- emails.loader.from_file(filename, \*\*kwargs)¶
Create a message from a single HTML file.
- Parameters:
filename – Path to the HTML file.
kwargs – Additional options (
message_params).
- Returns:
A
Messageinstance.
- emails.loader.from_rfc822(msg, loader_cls=None, message_params=None, parse_headers=False)¶
Create a message from an RFC 822 email object (e.g., from
email.message). Primarily intended for demonstration and testing purposes.- Parameters:
msg – An
email.message.Messageobject.loader_cls – Custom loader class.
message_params – Additional parameters for the Message constructor.
parse_headers – If
True, parse and transfer email headers.
- Returns:
A
Messageinstance.
Loader Exceptions¶
- exception emails.loader.LoadError¶
Base exception for all loader errors.
- exception emails.loader.IndexFileNotFound¶
Raised when the loader cannot find an HTML index file in the source. Subclass of
LoadError.
- exception emails.loader.InvalidHtmlFile¶
Raised when the HTML content cannot be parsed. Subclass of
LoadError.
Templates¶
Template classes allow dynamic content in email bodies and subjects. Pass a
template instance as the html, text, or subject parameter of
Message.
Install template dependencies with extras:
pip install "emails[jinja]" # for JinjaTemplate
- class emails.template.JinjaTemplate(template_text, environment=None)¶
Template using Jinja2 syntax.
- Parameters:
template_text – Jinja2 template string.
environment – Optional
jinja2.Environmentinstance.
Example:
from emails.template import JinjaTemplate msg = emails.Message( html=JinjaTemplate("<p>Hello {{ name }}!</p>"), subject=JinjaTemplate("Welcome, {{ name }}"), mail_from="noreply@example.com" ) msg.send(render={"name": "Alice"}, smtp={"host": "localhost"})
- class emails.template.StringTemplate(template_text, safe_substitute=True)¶
Template using Python’s
string.Templatesyntax ($variableor${variable}).- Parameters:
template_text – Template string.
safe_substitute – If
True(default), undefined variables are left as-is. IfFalse, undefined variables raiseKeyError.
Example:
from emails.template import StringTemplate msg = emails.Message( html=StringTemplate("<p>Hello $name!</p>"), mail_from="noreply@example.com" )
DjangoMessage¶
A Message subclass for use with Django’s email backend.
- class emails.django.DjangoMessage(\*\*kwargs)¶
Accepts the same parameters as
Message. Integrates with Django’s email sending infrastructure.- send(mail_to=None, set_mail_to=True, mail_from=None, set_mail_from=False, context=None, connection=None, to=None)¶
Send the message through Django’s email backend.
- Parameters:
context – Dictionary of template rendering variables (equivalent to
renderinMessage.send()).connection – A Django email backend connection instance (e.g., from
django.core.mail.get_connection()). IfNone, uses the default backend.to – Alias for
mail_to.
- Returns:
1if the message was sent successfully,0otherwise.- Return type:
Example:
from emails.django import DjangoMessage msg = DjangoMessage( html="<p>Hello {{ name }}</p>", subject="Welcome", mail_from="noreply@example.com" ) msg.send(to="user@example.com", context={"name": "Alice"})
DKIM¶
DKIM (DomainKeys Identified Mail) signing is configured via the
Message.dkim() method (or its alias Message.sign()).
Parameters:
key– Private key in PEM format. Accepts a string, bytes, or file-like object.domain– The signing domain (e.g.,"example.com").selector– The DKIM selector (e.g.,"default").ignore_sign_errors– IfTrue, silently ignore signing errors instead of raising exceptions.Additional keyword arguments are passed to the DKIM library (e.g.,
canonicalize,signature_algorithm).
Returns the message instance (for chaining).
Example:
import emails
msg = emails.Message(
html="<p>Signed message</p>",
mail_from=("Sender", "sender@example.com"),
subject="DKIM Test"
)
msg.dkim(
key=open("private.pem").read(),
domain="example.com",
selector="default"
)
msg.send(to="recipient@example.com", smtp={"host": "localhost"})
The signature is automatically applied when the message is serialized
(via as_string(), as_bytes(), or send()).
Exceptions¶
- exception emails.HTTPLoaderError¶
Raised when loading content from a URL fails (e.g., HTTP error, connection timeout).
- exception emails.BadHeaderError¶
Raised when an email header contains invalid characters (such as newlines or carriage returns).
- exception emails.IncompleteMessage¶
Raised when attempting to send a message that lacks required content (no HTML and no text body).
See also the Loader Exceptions section for loader-specific exceptions:
LoadError, IndexFileNotFound, InvalidHtmlFile.
Utilities¶
- class emails.utils.MessageID(domain=None, idstring=None)¶
Generator for RFC 2822 compliant Message-ID values.
- Parameters:
domain – Domain part of the Message-ID. Defaults to the machine’s FQDN.
idstring – Optional additional string to strengthen uniqueness.
The instance is callable — each call generates a new unique Message-ID.
Example:
from emails.utils import MessageID # Auto-generate a new Message-ID for each send msg = emails.Message( message_id=MessageID(domain="example.com"), html="<p>Hello</p>", mail_from="sender@example.com" )