mailfixture
Email fixtures for your test suite. Create a programmatic inbox in one call, point your app's signup / OTP / password-reset flow at it, then wait for the email — parsed, with the OTP and links already extracted.
Receive-only, built for CI: long-polling instead of retry loops, zero dependencies outside the Python standard library, Python 3.9+.
pip install mailfixture
Quickstart
Create a key in Dashboard → API keys and
export it as MAILFIXTURE_API_KEY.
from mailfixture import MailFixture
mfx = MailFixture() # reads MAILFIXTURE_API_KEY
def test_signup_sends_otp(page):
inbox = mfx.create_inbox(ttl_seconds=900)
page.goto("/signup")
page.fill("#email", inbox.email_address)
page.click("text=Send code")
otp = inbox.wait_for_otp(timeout=30) # long-polls; no sleep()
page.fill("#otp", otp)
Waiting for a magic link instead:
link = inbox.wait_for_link(kind="verify", timeout=30)
page.goto(link.url)
Capturing a webhook your app sends:
hook = mfx.create_hook(label="checkout", ttl_seconds=900)
configure_app_webhook(hook.ingest_url) # your test setup
trigger_checkout()
request = hook.wait_for_request(match="body:order.created")
assert request.method == "POST"
hook.delete()
Everything on the wait helpers is server-side long-polling: the request is
held open until a matching message arrives (or the timeout passes, raising
mailfixture.MailFixtureTimeout).
API surface
| Method | Purpose |
|---|---|
create_inbox(local_part=, domain=, ttl_seconds=) |
new inbox; returns an Inbox handle |
inbox.wait_for_message(match=, timeout=) |
first matching message, full body + extraction |
inbox.wait_for_otp(match=, timeout=) |
best extracted OTP as a string |
inbox.wait_for_link(kind=, match=, timeout=) |
first link, optionally verify|reset|unsubscribe |
inbox.messages(since=, match=, wait=) / clear() / delete() |
raw listing & lifecycle |
get_message(id), get_otp(id), get_links(id) |
direct message access |
download_attachment(message_id, index) |
decoded attachment bytes |
create_hook(label=, ttl_seconds=), list_hooks() |
webhook capture URL and lifecycle handles |
hook.wait_for_request(match=, since=, timeout=) |
first matching captured request, including full headers and body |
hook.requests(...), clear(), delete() / get_hook_request(id) |
capture listing, teardown, and direct detail access |
create_domain(fqdn), verify_domain(id), list_domains(), delete_domain(id) |
custom domains |
create_key(label=), list_keys(), revoke_key(id) |
API keys |
match filters with subject:, from:, or to: prefixes; a bare term
matches the subject.
Capture-hook matching accepts method:, path:, and body:; a bare term
matches the first 32 KiB of request body bytes. Returned detail bodies are
complete.
Errors are raised as mailfixture.MailFixtureError carrying the API's
RFC 7807 status / title / detail fields.
Development
PYTHONPATH=src python3 -m unittest discover -s tests
Metadata
Release files for mailfixture 0.6.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 | |
|---|---|---|---|
| mailfixture-0.6.0.tar.gz | 20.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mailfixture-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 34.7 kB
Release files / mailfixture-0.6.0.tar.gz
| Download URL | mailfixture-0.6.0.tar.gz |
|---|---|
| Size | 20.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3bdbc85c242dd554a121dce1c3f1ea73e6d5cddb74eb6a8813abc6fd9b7f8314
|
|
BLAKE2b-256 checksum How to use checksums |
3ab3bf0802261f5220fb90570c2f8ef70eaffe8de4a3f65764af2ff851a8543a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","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":null}
|
Release files / mailfixture-0.6.0-py3-none-any.whl
| Download URL | mailfixture-0.6.0-py3-none-any.whl |
|---|---|
| Size | 14.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2afcc8d0f63c44624623bd1441a7cf263ea9fa8a9b717d77b91e23fd83ef0217
|
|
BLAKE2b-256 checksum How to use checksums |
7910a0c560f058f7a2bee7aa5df05461d2a6721811f63fa4c32635f061a58347
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","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":null}
|