micromailer
Ultra-fast, modular, zero-dependency async email engine for Python 3.12+.
- Zero runtime dependencies
- Async SMTP via stdlib
smtplib(works on 3.12, 3.13, 3.14) - HTTP API backend for Resend / SES-style providers
SMTPPoolfor connection reuse in bulk sendsvalidate_htmlandrender_templateutilities- PEP 561 typed package (
py.typed)
Install
pip install micromailer
Quick start
import asyncio
from micromailer import AsyncSMTPMailer
async def main() -> None:
async with AsyncSMTPMailer(
host="smtp.gmail.com",
port=587,
username="you@gmail.com",
password="app-password",
) as mailer:
await mailer.send(
to="friend@example.com",
subject="Hello",
html_body="<p>Hi</p>",
)
asyncio.run(main())
Sending patterns
All patterns are async-first. Use async with so the connection is always closed.
Single recipient
await mailer.send(
to="alex@example.com",
subject="Your grade",
html_body="<p>Grade: A</p>",
)
Multiple recipients
await mailer.send(
to=["alex@example.com", "jordan@example.com"],
subject="Your grade",
html_body="<p>Grade: A</p>",
)
Custom sender
await mailer.send(
to="alex@example.com",
subject="Hi",
html_body="<p>Hello</p>",
sender="registrar@university.edu",
)
Plain-text email
text = "Hello,\n\nYour grade is A.\n"
html = f"<pre>{text}</pre>"
await mailer.send(to="alex@example.com", subject="Grade", html_body=html)
HTML email with inline CSS
html = """
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
<h1 style="color: #1a73e8;">Results</h1>
<p style="color: #444;">Grade: <strong>A</strong></p>
</div>
"""
await mailer.send(to="alex@example.com", subject="Results", html_body=html)
Implicit TLS (port 465)
async with AsyncSMTPMailer(
host="smtp.gmail.com",
port=465,
username="you@gmail.com",
password="app-password",
use_tls=True,
) as mailer:
await mailer.send(to="friend@example.com", subject="Hello", html_body="<p>Hi</p>")
Bulk sends with SMTPPool
from micromailer import SMTPPool
async def bulk(contacts: list[dict]) -> None:
async with SMTPPool(max_size=5, host="smtp.gmail.com", port=587,
username="you@gmail.com", password="app-password") as pool:
for contact in contacts:
mailer = await pool.acquire()
try:
await mailer.send(
to=contact["email"],
subject="Newsletter",
html_body="<p>Hello</p>",
)
finally:
await pool.release(mailer)
HTTP API backend (Resend / SES)
from micromailer import AsyncHTTPMailer
async def send_via_api() -> None:
async with AsyncHTTPMailer(api_key="re_xxx", base_url="https://api.resend.com") as mailer:
await mailer.send(
to="alex@example.com",
subject="Hello",
html_body="<p>Hi from API</p>",
)
Error handling
from micromailer.core.base import SMTPError
try:
await mailer.send(to="alex@example.com", subject="Hi", html_body="<p>Hi</p>")
except SMTPError as e:
print(f"SMTP failed: {e.code} -> {e}")
except Exception as e:
print(f"Unexpected error: {type(e).__name__} -> {e}")
Utilities
from micromailer import validate_html, render_template, encode_base64
validate_html("<div><p>ok</p></div>") # []
validate_html("<div><p>oops</div>") # ["Unclosed tag <div>", ...]
render_template("Hi {name}", {"name": "Alex"}) # "Hi Alex"
encode_base64("raw bytes") # "cmF3IGJ5dGVz"
Module layout
core.base—MailerBackendprotocol,SMTPError,MailerResult,MailerBatchcore.smtp—AsyncSMTPMailercore.http—AsyncHTTPMailercore.pool—SMTPPoolutils.mime—validate_html,render_template,encode_base64,decode_base64
Release files for micromailer 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| micromailer-1.0.0.tar.gz | 5.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| micromailer-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 14.1 kB
Release files / micromailer-1.0.0.tar.gz
| Download URL | micromailer-1.0.0.tar.gz |
|---|---|
| Size | 5.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5d02dbf2bfbf74fd802b531b72923a5148bdb2375e3270dd0310a76ef177eb18
|
|
BLAKE2b-256 checksum How to use checksums |
eb6af52ee6ba884b4ca28ea9880483705e0c3b69c7e66710dbdbd33d1f7d396d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / micromailer-1.0.0-py3-none-any.whl
| Download URL | micromailer-1.0.0-py3-none-any.whl |
|---|---|
| Size | 8.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c14deea18237f3044c4dd2891b11d2709d04b4f3464ff296cce02d19668c5042
|
|
BLAKE2b-256 checksum How to use checksums |
28a2daca364c8bd807b0d2ddb0fba4389fb625d2f1d9081665c3d636e32f0723
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|