Skip to main content

Zero-config email interceptor for Python ASGI apps

Project description

Mailview

Mailview

Capture outgoing emails during development and view them in a browser UI mounted inside your app.

No Docker. No SMTP server. No external services. Just one line of middleware.
Inspired by Ruby's letter_opener.

CI CodeQL PyPI Python Coverage License

Installation

pip install mailview

Quick Start

from fastapi import FastAPI
from mailview import MailviewMiddleware

app = FastAPI()
app.add_middleware(MailviewMiddleware)

That's it. Visit /_mail in your browser to see captured emails.

Features

  • Zero config - add middleware, visit /_mail, done
  • Persistent storage - emails survive dev server restarts (SQLite in temp dir)
  • Full email support - HTML, plaintext, multipart, attachments
  • Sandboxed preview - HTML emails render in an iframe without CSS bleed
  • Dev-only by default - refuses to activate in production environments
  • Self-contained - no external assets, works fully offline

How It Works

Mailview provides drop-in email backends that intercept outgoing emails instead of sending them:

# FastAPI-Mail
from mailview.backend import MailviewBackend
from fastapi_mail import FastMail, ConnectionConfig

config = ConnectionConfig(
    MAIL_BACKEND=MailviewBackend,
    # ... other config
)

# Or with any SMTP-based library, point it at Mailview's capture backend

Captured emails are stored in SQLite at /tmp/mailview/mailview.db and served through the /_mail UI.

Browser UI

Navigate to /_mail to see:

  • Inbox - list of captured emails with sender, recipients, subject, timestamp
  • HTML preview - rendered email in a sandboxed iframe
  • Plaintext - raw text version
  • Source - raw email headers and body
  • Attachments - download any attached files

Clear all emails with the delete button or DELETE /_mail/api/emails.

Screenshots

Source Tab Source Tab

Headers Table Headers Table

Text Tab Text Tab

Copy Button Copy Button

Configuration

Mailview works with zero configuration, but you can customise if needed:

app.add_middleware(
    MailviewMiddleware,
    mount_path="/_mail",        # Change the UI path (default: /_mail)
    db_path="/custom/path.db",  # Custom SQLite location (default: /tmp/mailview/mailview.db)
    enabled=True,               # Force enable/disable (default: auto-detect dev environment)
)

Production Safety

Mailview will not activate unless it detects a development environment. It checks for:

  • DEBUG=true or DEBUG=1 environment variable
  • MAILVIEW_ENABLED=true to explicitly enable
  • Framework-specific debug flags (FastAPI's debug=True, etc.)

To be extra safe, don't include mailview in your production dependencies.

Network Binding Warning

Mailview has no authentication. If your dev server binds to 0.0.0.0 (all interfaces) instead of 127.0.0.1 (localhost only), anyone on your local network can access /_mail and view captured emails.

For local development, prefer:

uvicorn app:app --host 127.0.0.1 --port 8000

Framework Support

Framework Status
FastAPI ✅ Supported
Starlette ✅ Supported
Django 🔜 Planned
Flask 🔜 Planned

Requirements

  • Python: 3.11+
  • Starlette: 0.40.0+
  • FastAPI: 0.115.5+ (if using FastAPI)

API Endpoints

The UI is powered by a simple JSON API:

Method Path Description
GET /_mail/api/emails List all captured emails
GET /_mail/api/emails/{id} Get a single email
GET /_mail/api/emails/{id}/html Get HTML body
GET /_mail/api/emails/{id}/attachments/{filename} Download attachment
DELETE /_mail/api/emails Clear all emails
DELETE /_mail/api/emails/{id} Delete a single email

Development

git clone https://github.com/swmcc/mailview.git
cd mailview
make local.install
make local.check

See CONTRIBUTING.md for full development workflow.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mailview-0.1.0.tar.gz (1.1 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mailview-0.1.0-py3-none-any.whl (24.2 kB view details)

Uploaded Python 3

File details

Details for the file mailview-0.1.0.tar.gz.

File metadata

  • Download URL: mailview-0.1.0.tar.gz
  • Upload date:
  • Size: 1.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mailview-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9d7af80f4c523a7c5980126afa6e609db3be2788f571f1aa38a70232ca9080b4
MD5 01e3c8049f12d12a63497f1e88f3f902
BLAKE2b-256 84bf80de193f7559d57375ef7c78f506d27d23e5d1d034b23899f01e0a8843a7

See more details on using hashes here.

Provenance

The following attestation bundles were made for mailview-0.1.0.tar.gz:

Publisher: release.yml on swmcc/mailview

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mailview-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: mailview-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 24.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mailview-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cbe58161c0daac13a6c6f6c79fe3ff9e714abd3afa423c0fd58f5117fc971a3e
MD5 61b9bfa0a5a1d47d7ce3c1f6a7087faa
BLAKE2b-256 d4a9c44a7df2f9413de91c0f1e3be166f741fd507afbdf86643a991d21396dd9

See more details on using hashes here.

Provenance

The following attestation bundles were made for mailview-0.1.0-py3-none-any.whl:

Publisher: release.yml on swmcc/mailview

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page