Async Python client for the mail.gw API
Project description
mailgw-python
Async Python client for the mail.gw API.
It helps you:
- list available domains
- create and manage temporary mail accounts
- read mailbox messages
- listen for new messages in real time (Mercure/SSE webhook-like stream)
- fetch raw source of a message
Requirements
- Python 3.10+
Installation
Poetry
poetry add mailgw-python
pip (from PyPI)
pip install mailgw-python
pip (specific version)
pip install "mailgw-python==0.1.0"
pip (from TestPyPI)
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple mailgw-python
pip (from GitHub)
pip install "git+https://github.com/<your-user>/<your-repo>.git"
pip (from local source)
pip install .
Client Lifecycle
You can create the client directly:
client = MailGWClient()
async with MailGWClient() is also supported and is usually preferred, because the client connection closes automatically.
Quick Start
import asyncio
import uuid
from mailgw import MailGWClient
async def main():
client = MailGWClient()
domains = await client.domains.get()
domain = domains.hydra_member[0].domain
address = f"{uuid.uuid4()}@{domain}"
password = str(uuid.uuid4())
account = await client.accounts.create(address, password)
token_data = await client.token.get_token(address, password)
token = token_data.token
messages = await client.messages.reads(token)
print(f"Mailbox has {messages.total_items} messages")
await client.accounts.delete_by_id(account.id, token)
if __name__ == "__main__":
asyncio.run(main())
API Usage Examples
1) Get all domains
import asyncio
from mailgw import MailGWClient
async def main():
client = MailGWClient()
domains = await client.domains.get(page=1)
for item in domains.hydra_member or []:
print(item.domain, item.is_active)
if __name__ == "__main__":
asyncio.run(main())
2) Get one domain by ID
import asyncio
from mailgw import MailGWClient
async def main():
client = MailGWClient()
domain = await client.domains.get_by_id("your-domain-id")
print(domain)
if __name__ == "__main__":
asyncio.run(main())
3) Create one account
import asyncio
import uuid
from mailgw import MailGWClient
async def main():
client = MailGWClient()
domains = await client.domains.get()
domain = domains.hydra_member[0].domain
address = f"{uuid.uuid4()}@{domain}"
password = str(uuid.uuid4())
account = await client.accounts.create(address, password)
print("Account ID:", account.id)
print("Address:", account.address)
if __name__ == "__main__":
asyncio.run(main())
4) Authenticate and get token
import asyncio
from mailgw import MailGWClient
async def main():
client = MailGWClient()
token_data = await client.token.get_token(
address="user@your-domain.tld",
password="your-password",
)
print("Token:", token_data.token)
if __name__ == "__main__":
asyncio.run(main())
5) Get current account (/me)
import asyncio
from mailgw import MailGWClient
async def main():
client = MailGWClient()
me = await client.accounts.me("your-jwt-token")
print(me.id, me.address)
if __name__ == "__main__":
asyncio.run(main())
6) Get all messages
import asyncio
from mailgw import MailGWClient
async def main():
client = MailGWClient()
messages = await client.messages.reads("your-jwt-token")
print("Total:", messages.total_items)
for message in messages.messages:
print(message.id, message.subject)
if __name__ == "__main__":
asyncio.run(main())
7) Get one message by ID
import asyncio
from mailgw import MailGWClient
async def main():
client = MailGWClient()
message = await client.messages.read_by_id(
message_id="your-message-id",
token="your-jwt-token",
)
print(message.subject)
print(message.text)
if __name__ == "__main__":
asyncio.run(main())
8) Get raw message source
import asyncio
from mailgw import MailGWClient
async def main():
client = MailGWClient()
source = await client.sources.get_source_message(
message_id="your-message-id",
token="your-jwt-token",
)
print(source.data)
if __name__ == "__main__":
asyncio.run(main())
9) Receive messages via webhook-like stream (SSE)
listen_messages subscribes to the Mail.gw Mercure topic for your account and yields new Message events.
import asyncio
import httpx
from mailgw import MailGWClient
async def main():
account_id = "your-account-id"
token = "your-jwt-token"
client = MailGWClient()
try:
async for event in client.messages.listen_messages(account_id, token):
full_message = await client.messages.read_by_id(event.id, token)
print("New message:", full_message.subject)
break
except httpx.ReadTimeout:
print("No new messages within timeout window")
if __name__ == "__main__":
asyncio.run(main())
10) Forward new messages to your own webhook URL
If you need classic HTTP webhooks, subscribe via SSE and forward each event to your endpoint.
import asyncio
import httpx
from mailgw import MailGWClient
async def main():
account_id = "your-account-id"
token = "your-jwt-token"
webhook_url = "https://your-service.example/webhooks/mailgw"
client = MailGWClient()
async with httpx.AsyncClient(timeout=10.0) as webhook_client:
async for event in client.messages.listen_messages(account_id, token):
message = await client.messages.read_by_id(event.id, token)
await webhook_client.post(
webhook_url,
json={
"id": message.id,
"subject": message.subject,
"intro": message.intro,
"text": message.text,
"created_at": message.created_at,
},
)
if __name__ == "__main__":
asyncio.run(main())
Resource Methods
client.domains
get(page: int = 1)get_by_id(domain_id: str)
client.accounts
create(address: str, password: str)me(token: str)read_by_id(account_id: str, token: str)delete_by_id(account_id: str, token: str)
client.token
get_token(address: str, password: str)
client.messages
reads(token: str)read_by_id(message_id: str, token: str)listen_messages(account_id: str, token: str, read_timeout: float | None = 120.0)
client.sources
get_source_message(message_id: str, token: str)
Error Handling
All API errors raise mailgw.exceptions.APIError.
import asyncio
from mailgw import MailGWClient
from mailgw.exceptions import APIError
async def main():
client = MailGWClient()
try:
await client.accounts.me("invalid-token")
except APIError as e:
print(f"Status: {e.status_code}")
print(f"Message: {e.message}")
if __name__ == "__main__":
asyncio.run(main())
Notes
- You can use
client = MailGWClient()directly. async with MailGWClient()is usually preferred because the client connection is closed automatically.- You can override request timeout:
MailGWClient(timeout=5.0). - Real-time updates use Mercure Server-Sent Events (SSE).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mailgw_python-0.1.1.tar.gz.
File metadata
- Download URL: mailgw_python-0.1.1.tar.gz
- Upload date:
- Size: 5.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7aea555be39a96ac39da77ee5623d688fa2f5b13bbc7969889953ce09d9e0ac1
|
|
| MD5 |
55ae131cb270577f0c371839eefc97f6
|
|
| BLAKE2b-256 |
c994a917235a3f0331065186c3e429ae4fd6fc090d5686bd495af06f903da7b4
|
File details
Details for the file mailgw_python-0.1.1-py3-none-any.whl.
File metadata
- Download URL: mailgw_python-0.1.1-py3-none-any.whl
- Upload date:
- Size: 10.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
34a4c3c4a694f4bb43a0c42dee2d8f1e2c8084b791add188aeab9bb547d32929
|
|
| MD5 |
55082e7af46caf6f9775189c3a4214e5
|
|
| BLAKE2b-256 |
577c6f1823b13498a8fec38ea1fa577cc817279f6079ac381f62fe1e355637aa
|