Skip to main content

stapel-mailtrap

CI coverage pypi downloads python license llms.txt

An email trap (mail catcher) for dev/staging: outbound mail is captured into a TrappedEmail journal instead of being sent, and browsed through a read-only "Mail" API. Plugs into stapel-notifications' email-provider seam by dotted path — no module-to-module import.

Part of the Stapel framework — composable Django apps that deploy as a monolith or as microservices without changing module code.

Install

pip install stapel-mailtrap
# settings.py
INSTALLED_APPS = [
    # ...
    "stapel_mailtrap",
]

# urls.py
path("mailtrap/", include("stapel_mailtrap.urls"))
python manage.py migrate

Trapping notifications email

Point stapel-notifications' email provider at the trap — one setting, no code:

STAPEL_NOTIFICATIONS = {
    "EMAIL_PROVIDER": "stapel_mailtrap.provider.MailtrapEmailProvider",
}

Every email stapel-notifications would send is now persisted and inspectable instead. The provider matches the notifications email duck type (send(recipient, subject, html_body, headers)) — see MODULE.md §3.

Trapping any backend

For a host whose own mail path should trap, call the service directly:

from stapel_mailtrap import trap_email

trap_email(
    to_email="alice@example.com",
    from_email="bot@example.com",
    subject="Your code",
    body_html="<b>123456</b>",
    body_text="123456",
    attachments=[{"filename": "invoice.pdf", "content_type": "application/pdf", "size": 8123}],
    scope_key="workspace-42",   # opaque host scope
)

It persists the row and emits mailtrap.email.trapped transactionally. Attachments are metadata only — raw bytes are never stored.

HTTP API ("Письма" / Mail)

Read-only (the trap is filled by the provider / trap_email, never via the API):

Route Meaning
GET mailtrap/emails/ Trapped emails, newest first, paginated (anchor); ?scope_key= filters
GET mailtrap/emails/<uuid>/ One trapped email — full HTML/text bodies + attachment metadata

Default permission is staff/service only (trapped mail can contain OTPs and magic links). Override permission_classes and set a SCOPE_PROVIDER for per-tenant visibility — see MODULE.md.

Retention

STAPEL_MAILTRAP = {
    "MAX_EMAILS": 1000,   # hard cap on stored rows (0 disables)
    "TTL_DAYS": 30,       # delete rows older than N days (0 disables)
}

Run the sweep from any scheduler:

python manage.py purge_trapped_emails            # --dry-run supported

Or schedule the Celery task (celery is an optional host dependency):

CELERY_BEAT_SCHEDULE = {
    "purge-trapped-emails": {
        "task": "stapel_mailtrap.tasks.purge_trapped_emails",
        "schedule": crontab(hour=3, minute=0),   # nightly
    },
}

Settings

All configuration lives in the STAPEL_MAILTRAP namespace (dict setting, flat setting, or env var — resolved lazily):

Key Default Meaning
SCOPE_PROVIDER "stapel_mailtrap.scope.DefaultScopeProvider" Dotted path to a ScopeProvider subclass — the multi-tenant seam.
MAX_EMAILS 1000 Retention count cap (0 disables).
TTL_DAYS 30 Retention age cap in days (0 disables).
STORE_BODY True False stores the envelope only (bodies empty).

comm surface

Kind Name Contract
Event mailtrap.email.trapped {email_id, to, from?, subject, scope_key, attachment_count, trapped_at} — schema

Extension points

See MODULE.md — the agent-facing map of every fork-free seam (settings, the ScopeProvider seam, the notifications email-provider adapter with its duck-typed contract, serializer seams, permissions, comm surface, system checks).

Development

pip install -e . && pip install pytest pytest-django pytest-cov ruff jsonschema
./setup-hooks.sh
pytest tests/

License

MIT

Metadata

Release files for stapel-mailtrap 0.1.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for stapel-mailtrap 0.1.8
File Size Uploaded
stapel_mailtrap-0.1.8.tar.gz 24.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for stapel-mailtrap 0.1.8
File Interpreter ABI Platform
stapel_mailtrap-0.1.8-py3-none-any.whl Python 3 none any Details

Total release size: 51.7 kB

Release files / stapel_mailtrap-0.1.8.tar.gz

Download URL stapel_mailtrap-0.1.8.tar.gz
Size 24.6 kB
Tags Source
SHA-256 checksum
How to use checksums
dc1a17f50d2eda94f54eca16d0a20ecfe0c45d003dc703b4adc63cb40212b4d9
BLAKE2b-256 checksum
How to use checksums
307b44500ff65a407d42f11c913ee9bf777741490580b04f63c4d55c0920d0a4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 2, 2026.

Transparency log

Release files / stapel_mailtrap-0.1.8-py3-none-any.whl

Download URL stapel_mailtrap-0.1.8-py3-none-any.whl
Size 27.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3372dc16ae1e626ffc0a5f1114c2b14e768d5e1e6b57a7c723812b15ee2e92f2
BLAKE2b-256 checksum
How to use checksums
4f72527cfa0374e8b9edfb54852adae651006d66f32c1f34d758934a6abe1102
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.8 This release

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

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