simmail (Python)
The official Python client for simmail: a simulated email world for testing apps and email agents. Wait for the email your app sends, pull out the code or link, and get replies from simulated people, in a few lines of test code.
Standard library only; Python 3.9 or newer. Full docs: https://www.simmail.dev/docs/
pip install simmail
Setup
The client reads its settings from the environment (or pass them to Simmail(...)):
| Variable | Meaning |
|---|---|
SIMMAIL_URL |
Your universe's server, such as https://c1.simmail.dev (shown on your account page). |
SIMMAIL_API_KEY |
An API key, smk_… (Organization → API keys). |
SIMMAIL_UNIVERSE |
Optional: only needed when the key could reach more than one universe. |
Your app sends through simmail's SMTP as usual (the dashboard's Get started shows the settings); this client is for your tests. Results are plain dictionaries with the API's field names.
Wait for an email and use its link (pytest)
import time
from simmail import Simmail
mail = Simmail()
def test_password_reset(client):
email = f"user-{int(time.time())}@yourcompany.test"
client.post("/signup", data={"email": email, "password": "pw-123456789"})
client.post("/forgot-password", data={"email": email})
msg = mail.wait_for_email(email, subject="reset", existing=True, timeout=20)
assert msg["magic_links"], msg["text"]
A wait only sees mail that arrives after it starts, unless you pass existing=True.
Timeouts are seconds, or a duration such as "45s" (at most five minutes).
Read what is there
inbox = mail.messages("user@yourcompany.test") # newest first
latest = mail.message("user@yourcompany.test", "INBOX", inbox[0]["uid"])
report = mail.health(latest["message_id"]) # spam score, links, compatibility
A conversation with a simulated person
sent = mail.send("sales@yourcompany.test", ["dana@harbor.test"], "Offer", text="Would you take 165k?")
reply = mail.wait_for_reply("dana@harbor.test", in_reply_to=sent["message_id"])
print(reply["text"])
mail.advance("2d") # move the simulated clock: follow-ups and nudges that were due happen
Errors
A failed call raises SimmailError with the HTTP status and the server's message.
License
Apache-2.0
Metadata
Release files for simmail 0.1.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 | |
|---|---|---|---|
| simmail-0.1.0.tar.gz | 9.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| simmail-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.0 kB
Release files / simmail-0.1.0.tar.gz
| Download URL | simmail-0.1.0.tar.gz |
|---|---|
| Size | 9.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9cbc518bebde18c4239a2712d805d8da49592077966f060d93a18944e4190e2d
|
|
BLAKE2b-256 checksum How to use checksums |
e4d38d6bf73d605d0aab70bc09382e4a0b8d65ba11078a6b314fceb0a79dd567
|
| 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 Oct 14, 2026.
Transparency logRelease files / simmail-0.1.0-py3-none-any.whl
| Download URL | simmail-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dea2c1df84257bc0bf603729ba3a6345eccd35c406bf1a6adf743fe80beb5a48
|
|
BLAKE2b-256 checksum How to use checksums |
d448cd2401f7a555e3ba71082cfe1d4ae263997bd89962e9b4126598cc34ccca
|
| 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 Oct 14, 2026.
Transparency log