Emailify
Create beautiful HTML emails with tables, text, images and more. Built on MJML for consistent rendering across all email clients. Images are embedded as proper email attachments with Content-ID references.
Installation
pip install emailify
Usage
Example
import pandas as pd
import emailify as ef
# The render function now returns both HTML and attachments
html, attachments = ef.render(
ef.Text(
text="Hello, this is a table with merged headers",
style=ef.Style(background_color="#cbf4c9", padding_left="5px"),
),
ef.Table(
data=df,
merge_equal_headers=True,
header_style={
"hello": ef.Style(background_color="#000000", font_color="#ffffff"),
},
column_style={
"hello3": ef.Style(background_color="#0d0d0", bold=True),
},
row_style={
1: ef.Style(background_color="#cbf4c9", bold=True),
},
),
ef.Fill(style=ef.Style(background_color="#cbf4c9")),
ef.Image(data=buf, format="png", width="600px"),
)
# html: ready-to-send HTML string
# attachments: list of email.mime.application.MIMEApplication objects for images
Result
Basic Table
Extra
Tables can also handle nested components.
import pandas as pd
import emailify as ef
df = pd.DataFrame({"Name": ["Alice", "Bob"], "Score": [95, 87]})
table = ef.Table(data=df)
html, attachments = ef.render(table)
# attachments will be empty since tables don't produce attachments
Text and Styling
text = ef.Text(
text="Hello, this is a styled header",
style=ef.Style(background_color="#cbf4c9", padding_left="5px")
)
html, attachments = ef.render(text)
Tables with Custom Styles
table = ef.Table(
data=df,
header_style={"Name": ef.Style(background_color="#000", font_color="#fff")},
column_style={"Score": ef.Style(background_color="#f0f0f0", bold=True)},
row_style={0: ef.Style(background_color="#e6ffe6")}
)
Images and Charts
import io
import matplotlib.pyplot as plt
# Create a chart
buf = io.BytesIO()
plt.plot([1, 2, 3], [2, 4, 1])
plt.savefig(buf, format="png", dpi=150)
plt.close()
buf.seek(0)
# Render with image - note that images produce attachments
image = ef.Image(data=buf, format="png", width="600px")
html, attachments = ef.render(image)
# attachments contains MIMEApplication objects with proper Content-ID headers
# The HTML references images via cid: URLs that match the Content-ID
print(f"Generated {len(attachments)} attachment(s)")
Key Features
- Responsive Design: Built on MJML for consistent rendering across Gmail, Outlook, Apple Mail, and other clients
- Proper Image Attachments: Images are embedded as email attachments with Content-ID references, not base64 data URIs
- Rich Components: Tables, text, images, and fills with extensive styling options
- Pandas Integration: Direct DataFrame rendering with customizable styles
- Type Safety: Full type hints and Pydantic models for robust development
Email Integration
The render() function returns a tuple of (html, attachments):
html: Ready-to-send HTML string withcid:references for imagesattachments: List ofMIMEApplicationobjects with proper headers for inline display
Use with your email library:
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
html, attachments = ef.render(your_components)
msg = MIMEMultipart('related')
msg.attach(MIMEText(html, 'html'))
for attachment in attachments:
msg.attach(attachment)
Metadata
Release files for emailify 0.1.18
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| emailify-0.1.18.tar.gz | 367.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| emailify-0.1.18-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 741.6 kB
Release files / emailify-0.1.18.tar.gz
| Download URL | emailify-0.1.18.tar.gz |
|---|---|
| Size | 367.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7b2b772b9fe8454f3764b4f91090d2fbbfae1d58305dad6f45fdf753dd5f3799
|
|
BLAKE2b-256 checksum How to use checksums |
b8a05396b7e3888060082b45bb8d22cfb5948ca9638e2aa61d83604a753e3a88
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.4 {"installer":{"name":"uv","version":"0.11.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / emailify-0.1.18-py3-none-any.whl
| Download URL | emailify-0.1.18-py3-none-any.whl |
|---|---|
| Size | 373.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
604a19213fcd6dc56508362624fd96303c99e2060c6c182edfb4f3f4d39a4675
|
|
BLAKE2b-256 checksum How to use checksums |
232d579bed810490f42ae944aa95d1e4b43ecdea225eb2f8be885823ee3f9ac7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.4 {"installer":{"name":"uv","version":"0.11.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|