Python Mailable is an email builder for Python, inspired by Laravel's Mailable class. It provides a clean and reusable structure for defining, composing, and rendering emails with rich context and templates.
Important
We currently only support rendering emails, not sending them.
This package helps you build and render email content using templates, but you need to handle email sending yourself with your own SMTP client or email delivery service.
- Define email classes with subjects, recipients, and templates
- Render HTML and plain-text versions from separate Jinja2 templates
- Pass context to templates for dynamic rendering
- Attach files easily
- Designed for clarity, testability, and reusability
Subclass Mailable and implement the build() method. Use the fluent API to configure the email.
from dataclasses import dataclass
from python_mailable import Mailable
@dataclass
class OrderShipped(Mailable):
user: User
def build(self):
return (
self.to(self.user.email)
.subject("Your order has shipped!")
.template("emails/order_shipped.html.j2")
.with_context({"user": self.user})
)email = OrderShipped(user).build()
html = email.render()Provide a separate plain-text template alongside the HTML template using text_template().
@dataclass
class OrderShipped(Mailable):
user: User
def build(self):
return (
self.to(self.user.email)
.subject("Your order has shipped!")
.template("emails/order_shipped.html.j2")
.text_template("emails/order_shipped.txt.j2")
.with_context({"user": self.user})
)Then render either version:
email = OrderShipped(user).build()
html = email.render()
text = email.render_as_text()render_as_text() returns None when no text template has been set. render() returns None when no HTML template has been set.
Pass the rendered content into your own delivery system:
email = OrderShipped(user).build()
your_mail_client.send(
to=email._to_email,
subject=email._subject_line,
html=email.render(),
text=email.render_as_text(),
)