Python SDK
pip install tropmailRequires Python 3.10+. The client reads TROPMAIL_API_KEY unless you pass the key.
Source: github.com/tropmail/tropmail-python
Quick start
from tropmail import TropMail
with TropMail() as client:
boxes = client.mailboxes.list()
mailbox = boxes[0]
print(f"{mailbox.email}: {mailbox.opened_count} opened")
for email in client.emails.iterate(mailbox_id=mailbox.id, status="Open"):
print(email.timestamp, email.from_.address, email.subject)Pass the key explicitly if you prefer:
client = TropMail("tm_live_your32charalphanumericapikeyhere")Async
import asyncio
from tropmail import AsyncTropMail
async def main() -> None:
async with AsyncTropMail() as client:
boxes = await client.mailboxes.list()
mailbox_id = boxes[0].id
async for email in client.emails.iterate(mailbox_id=mailbox_id, status="Favorite"):
print(email.subject)
asyncio.run(main())AsyncTropMail is the same surface as TropMail with await.
Reading an email
get() returns the HTML view by default. Pass the email object you already have instead of a bare id and the SDK forwards its timestamp for a faster lookup.
page = client.emails.list(mailbox_id=mailbox.id, limit=10)
email = page.emails[0]
detail = client.emails.get(mailbox.id, email, view="text")
print(detail.content)
for attachment in detail.attachments:
print(attachment.filename, attachment.size, attachment.scan_status)Markdown
The markdown view is generated on demand. get_markdown() retries 504 for you:
detail = client.emails.get_markdown(mailbox.id, email)
print(detail.content)Actions
client.emails.favorite(mailbox.id, email)
client.emails.close(mailbox.id, email)
client.emails.block(mailbox.id, email)
client.emails.clear_action(mailbox.id, email)Those are shorthands for update():
client.emails.update(mailbox.id, email, email_state="Open", action_status="Favorite")Search
page = client.emails.search("invoice", mailbox_id=mailbox.id, limit=25)
for email in client.emails.search_iterate("invoice", mailbox_id=mailbox.id):
print(email.subject)Search responses report total: 0. Iterators page until they see a short page.
Attachments
import time
info = client.attachments.get(mailbox.id, attachment_id)
print(info.filename, info.scan_status)
client.attachments.scan(mailbox.id, attachment_id)
while True:
info = client.attachments.get(mailbox.id, attachment_id)
if info.scan_status != "Processing":
break
time.sleep(2)
print(info.scan_status, info.scan_result)
path = client.attachments.download_to(mailbox.id, attachment_id, "/tmp/invoice.pdf")A file whose size is 0 is a real empty attachment. download_to writes an empty file.
Downloads use your API key on the same host as the rest of the API.
Errors
from tropmail import (
AuthenticationError, InvalidAPIKeyError, NotFoundError, RateLimitError,
TropMailError,
)
try:
client.emails.get(mailbox.id, "does-not-exist")
except NotFoundError as exc:
print(exc.status, exc.request_id)
except RateLimitError as exc:
print("retry after", exc.retry_after)
except TropMailError as exc:
print("request failed:", exc)Every error carries status, message, and request_id.
A missing or malformed key raises InvalidAPIKeyError before any HTTP call. HTTP 400 from the API is ValidationError.
| Exception | HTTP |
|---|---|
InvalidAPIKeyError | local (no request) |
ValidationError | 400 |
AuthenticationError | 401 |
TierError | 403 |
NotFoundError | 404 |
RateLimitError | 429 |
MarkdownTimeoutError | 504 |
ServerError | 5xx |
ConnectionError | transport failure |
Rate limits
The client reads X-RateLimit-* headers and stays within your account limit.
print(client.rate_limit)Disable pacing with TropMail(throttle=False) if you manage concurrency yourself.
Configuration
client = TropMail(
api_key=None, # else TROPMAIL_API_KEY
base_url="https://api.tropmail.com/api/v1",
timeout=120.0,
max_retries=3,
throttle=True,
)Retries with backoff on 429, 502, 503, 504, and transport errors. Reads retry. Mutations do not.
Examples
| File | What it shows |
|---|---|
quickstart.py | mailbox summary, listing, reading one message |
async_inbox.py | AsyncTropMail, concurrent reads |
save_attachments.py | scan and download to disk |