Skip to main content

micromailer

PyPI version PyPI Downloads Python Versions

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
  • SMTPPool for connection reuse in bulk sends
  • validate_html and render_template utilities
  • 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 — MailerBackend protocol, SMTPError, MailerResult, MailerBatch
  • core.smtp — AsyncSMTPMailer
  • core.http — AsyncHTTPMailer
  • core.pool — SMTPPool
  • utils.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)

Source distribution for micromailer 1.0.0
File Size Uploaded
micromailer-1.0.0.tar.gz 5.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for micromailer 1.0.0
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page