Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 37 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ client.send(mail)
### Sandbox vs Production (easy switching)

Mailtrap lets you test safely in the Email Sandbox and then switch to Production (Sending).
Remove the inbox_id field or set it to None. Then, remove the sandbox field or set it to False.
Remove the sandbox_id field or set it to None. Then, remove the sandbox field or set it to False.
You can change the arguments in the code or via another way. Here is an example using environment variables.

Set next environment variables:
```bash
MAILTRAP_API_KEY=your_api_token # https://mailtrap.io/api-tokens
MAILTRAP_USE_SANDBOX=true # true/false toggle
MAILTRAP_INBOX_ID=123456 # Only needed for sandbox
MAILTRAP_SANDBOX_ID=123456 # Only needed for sandbox
```

Bootstrap logic:
Expand All @@ -67,12 +67,12 @@ import mailtrap as mt

API_KEY = os.environ["MAILTRAP_API_KEY"]
IS_SANDBOX = os.environ.get("MAILTRAP_USE_SANDBOX", "true").lower() == "true"
INBOX_ID = os.environ.get("MAILTRAP_INBOX_ID")
SANDBOX_ID = os.environ.get("MAILTRAP_SANDBOX_ID")

client = mt.MailtrapClient(
token=API_KEY,
sandbox=IS_SANDBOX,
inbox_id=INBOX_ID, # None is ignored for production
sandbox_id=SANDBOX_ID, # None is ignored for production
)

# Create mail object
Expand Down Expand Up @@ -224,11 +224,11 @@ The same situation applies to both `client.batch_send()` and `client.sending_api
- Advanced sending – [`sending/advanced_sending.py`](examples/sending/advanced_sending.py)
- Advanced batch sending – [`sending/batch_advanced_sending.py`](examples/sending/batch_advanced_sending.py)

### Email Sandbox (Testing) API:
- Attachments management – [`testing/attachments.py`](examples/testing/attachments.py)
- Inboxes management – [`testing/inboxes.py`](examples/testing/inboxes.py)
- Messages management – [`testing/messages.py`](examples/testing/messages.py)
- Projects management – [`testing/projects.py`](examples/testing/projects.py)
### Email Sandbox API:
- Attachments management – [`sandbox/attachments.py`](examples/sandbox/attachments.py)
- Sandboxes management – [`sandbox/sandboxes.py`](examples/sandbox/sandboxes.py)
- Messages management – [`sandbox/messages.py`](examples/sandbox/messages.py)
- Projects management – [`sandbox/projects.py`](examples/sandbox/projects.py)

### Contacts API:
- Contacts management – [`contacts/contacts.py`](examples/contacts/contacts.py)
Expand All @@ -242,9 +242,9 @@ The same situation applies to both `client.batch_send()` and `client.sending_api
- Templates (experimental, `/api/templates`) – [`paginated_templates/templates.py`](examples/paginated_templates/templates.py)
- Templates management – [`email_templates/templates.py`](examples/email_templates/templates.py)

### Sending Domains API:
- Sending Domains – [`sending_domains/sending_domains.py`](examples/sending_domains/sending_domains.py)
- Sending Domain Company Info – [`company_info/company_info.py`](examples/company_info/company_info.py)
### Domains API:
- Domains – [`domains/domains.py`](examples/domains/domains.py)
- Domain Company Info – [`company_info/company_info.py`](examples/company_info/company_info.py)

### Inbound Email API:
- Folders management – [`inbound/folders.py`](examples/inbound/folders.py)
Expand Down Expand Up @@ -281,6 +281,31 @@ The same situation applies to both `client.batch_send()` and `client.sending_api
### Organizations API:
- Sub-Accounts management – [`organizations/sub_accounts.py`](examples/organizations/sub_accounts.py)

## Renamed APIs

Email Sandbox inboxes are now called sandboxes, and sending domains are now called domains.
The old names still work and will be removed in a future major release.
The old client properties, methods, constructor arguments and keyword arguments raise a `DeprecationWarning`; the old model and params names are plain aliases and don't warn.
Comment thread
Rabsztok marked this conversation as resolved.
Resolved
API requests are the same with either name.

| Old name | New name |
|---|---|
| `MailtrapClient(inbox_id=...)` | `MailtrapClient(sandbox_id=...)` |
| `client.inbox_id` | `client.sandbox_id` |
| `client.testing_api` (`TestingApi`) | `client.sandbox_api` (`SandboxApi`) |
| `client.testing_api.inboxes` (`InboxesApi`) | `client.sandbox_api.sandboxes` (`SandboxesApi`) |
| `inbox_id=`, `inbox_params=` keyword arguments of the sandbox, message and attachment methods | `sandbox_id=`, `sandbox_params=` |
| `Inbox`, `CreateInboxParams`, `UpdateInboxParams` | `Sandbox`, `CreateSandboxParams`, `UpdateSandboxParams` |
| `SendingApi(inbox_id=...)` | `SendingApi(sandbox_id=...)` |
| `client.sending_domains_api` (`SendingDomainsBaseApi`) | `client.domains_api` (`DomainsBaseApi`) |
| `client.sending_domains_api.sending_domains` (`SendingDomainsApi`) | `client.domains_api.domains` (`DomainsApi`) |
| `sending_domain_id=` keyword argument of the domain and company info methods | `domain_id=` |
| `SendingDomain`, `SendingDomainPermissions`, `CreateSendingDomainParams`, `UpdateSendingDomainParams` | `Domain`, `DomainPermissions`, `CreateDomainParams`, `UpdateDomainParams` |

Fields that mirror the API response or query parameters keep their names, for example `EmailMessage.inbox_id`, `Project.inboxes` and `sending_domain_ids`. Email Inbound inboxes are not renamed.

Python hides `DeprecationWarning` outside `__main__` by default. To see the warnings, run with `python -W default::DeprecationWarning`.

## Contributing

Bug reports and pull requests are welcome on [GitHub](https://github.com/mailtrap/mailtrap-python). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](CODE_OF_CONDUCT.md).
Expand Down
65 changes: 65 additions & 0 deletions examples/domains/domains.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import os

import mailtrap as mt
from mailtrap.models.common import DeletedObject
from mailtrap.models.domains import Domain
from mailtrap.models.domains import SendSetupInstructionsResponse

API_KEY = os.environ["MAILTRAP_API_KEY"]
ACCOUNT_ID = os.environ["MAILTRAP_ACCOUNT_ID"]

client = mt.MailtrapClient(token=API_KEY, account_id=ACCOUNT_ID)
domains_api = client.domains_api.domains


def list_domains() -> list[Domain]:
return domains_api.get_list()


def get_domain(domain_id: int) -> Domain:
return domains_api.get_by_id(domain_id)


def create_domain(domain_name: str) -> Domain:
params = mt.CreateDomainParams(domain_name=domain_name)
return domains_api.create(params)


def update_domain(domain_id: int) -> Domain:
params = mt.UpdateDomainParams(
open_tracking_enabled=True,
click_tracking_enabled=True,
tracking_opt_out_enabled=True,
auto_unsubscribe_link_enabled=False,
inbound_enabled=False,
)
return domains_api.update(domain_id, params)


def delete_domain(domain_id: int) -> DeletedObject:
return domains_api.delete(domain_id)


def send_setup_instructions(domain_id: int, email: str) -> SendSetupInstructionsResponse:
params = mt.SendSetupInstructionsParams(email=email)
return domains_api.send_setup_instructions(domain_id, params)


if __name__ == "__main__":
new_domain = create_domain("example.com")
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
print(new_domain)

domains = list_domains()
print(domains)

domain = get_domain(new_domain.id)
print(domain)

updated_domain = update_domain(new_domain.id)
print(updated_domain)

response = send_setup_instructions(new_domain.id, "example@mail.com")
print(response)

deleted_domain = delete_domain(new_domain.id)
print(deleted_domain)
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,30 @@

API_KEY = os.environ["MAILTRAP_API_KEY"]
ACCOUNT_ID = os.environ["MAILTRAP_ACCOUNT_ID"]
INBOX_ID = os.environ["MAILTRAP_INBOX_ID"]
SANDBOX_ID = os.environ["MAILTRAP_SANDBOX_ID"]
MESSAGE_ID = os.environ["MAILTRAP_SANDBOX_MESSAGE_ID"]

client = mt.MailtrapClient(token=API_KEY, account_id=ACCOUNT_ID)
attachments_api = client.testing_api.attachments
attachments_api = client.sandbox_api.attachments


def list_attachments(inbox_id: int, message_id: int) -> list[Attachment]:
return attachments_api.get_list(inbox_id=inbox_id, message_id=message_id)
def list_attachments(sandbox_id: int, message_id: int) -> list[Attachment]:
return attachments_api.get_list(sandbox_id=sandbox_id, message_id=message_id)


def get_attachment(inbox_id: int, message_id: int, attachment_id: int) -> Attachment:
def get_attachment(sandbox_id: int, message_id: int, attachment_id: int) -> Attachment:
return attachments_api.get(
inbox_id=inbox_id,
sandbox_id=sandbox_id,
message_id=message_id,
attachment_id=attachment_id,
)


if __name__ == "__main__":
attachments = list_attachments(inbox_id=INBOX_ID, message_id=MESSAGE_ID)
attachments = list_attachments(sandbox_id=SANDBOX_ID, message_id=MESSAGE_ID)
print(attachments)
if attachments:
attachment = get_attachment(
inbox_id=INBOX_ID, message_id=MESSAGE_ID, attachment_id=attachments[0].id
sandbox_id=SANDBOX_ID, message_id=MESSAGE_ID, attachment_id=attachments[0].id
)
print(attachment)
122 changes: 122 additions & 0 deletions examples/sandbox/messages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import os
from typing import Any
from typing import Optional

import mailtrap as mt
from mailtrap.models.messages import AnalysisReport
from mailtrap.models.messages import EmailMessage
from mailtrap.models.messages import ForwardedMessage
from mailtrap.models.messages import SpamReport

API_KEY = os.environ["MAILTRAP_API_KEY"]
ACCOUNT_ID = os.environ["MAILTRAP_ACCOUNT_ID"]
SANDBOX_ID = os.environ["MAILTRAP_SANDBOX_ID"]

client = mt.MailtrapClient(token=API_KEY, account_id=ACCOUNT_ID)
messages_api = client.sandbox_api.messages


def get_message(sandbox_id: int, message_id: int) -> EmailMessage:
return messages_api.show_message(sandbox_id=sandbox_id, message_id=message_id)


def update_message(sandbox_id: int, message_id: int, is_read: bool) -> EmailMessage:
return messages_api.update(
sandbox_id=sandbox_id,
message_id=message_id,
message_params=mt.UpdateEmailMessageParams(is_read=is_read),
)


def delete_message(sandbox_id: int, message_id: int) -> EmailMessage:
return messages_api.delete(sandbox_id=sandbox_id, message_id=message_id)


def list_messages(
sandbox_id: int,
search: Optional[str] = None,
last_id: Optional[int] = None,
page: Optional[int] = None,
) -> list[EmailMessage]:
return messages_api.get_list(
sandbox_id=sandbox_id, search=search, last_id=last_id, page=page
)


def forward_message(sandbox_id: int, message_id: int, email: str) -> ForwardedMessage:
return messages_api.forward(sandbox_id=sandbox_id, message_id=message_id, email=email)


def get_spam_report(sandbox_id: int, message_id: str) -> SpamReport:
return messages_api.get_spam_report(sandbox_id=sandbox_id, message_id=message_id)


def get_html_analysis(sandbox_id: int, message_id: str) -> AnalysisReport:
return messages_api.get_html_analysis(sandbox_id=sandbox_id, message_id=message_id)


def get_text_message(sandbox_id: int, message_id: str) -> str:
return messages_api.get_text_message(sandbox_id=sandbox_id, message_id=message_id)


def get_raw_message(sandbox_id: int, message_id: str) -> str:
return messages_api.get_raw_message(sandbox_id=sandbox_id, message_id=message_id)


def get_html_source(sandbox_id: int, message_id: str) -> str:
return messages_api.get_html_source(sandbox_id=sandbox_id, message_id=message_id)


def get_html_message(sandbox_id: int, message_id: str) -> str:
return messages_api.get_html_message(sandbox_id=sandbox_id, message_id=message_id)


def get_message_as_eml(sandbox_id: int, message_id: str) -> str:
return messages_api.get_message_as_eml(sandbox_id=sandbox_id, message_id=message_id)


def get_mail_headers(sandbox_id: int, message_id: str) -> dict[str, Any]:
Comment thread
Rabsztok marked this conversation as resolved.
Resolved
return messages_api.get_mail_headers(sandbox_id=sandbox_id, message_id=message_id)


if __name__ == "__main__":
messages = list_messages(sandbox_id=SANDBOX_ID)
print(messages)
if messages:
msg_id = messages[0].id
message = get_message(sandbox_id=SANDBOX_ID, message_id=msg_id)
print(message)

updated = update_message(sandbox_id=SANDBOX_ID, message_id=msg_id, is_read=True)
print(updated)

forwarded = forward_message(
sandbox_id=SANDBOX_ID,
message_id=msg_id,
email="example@example.com",
)
print(forwarded)

spam = get_spam_report(sandbox_id=SANDBOX_ID, message_id=msg_id)
print(spam)

html_analysis = get_html_analysis(sandbox_id=SANDBOX_ID, message_id=msg_id)
print(html_analysis)

text = get_text_message(sandbox_id=SANDBOX_ID, message_id=msg_id)
print(text)

raw = get_raw_message(sandbox_id=SANDBOX_ID, message_id=msg_id)
print(raw)

html_src = get_html_source(sandbox_id=SANDBOX_ID, message_id=msg_id)
print(html_src)

html_msg = get_html_message(sandbox_id=SANDBOX_ID, message_id=msg_id)
print(html_msg)

eml = get_message_as_eml(sandbox_id=SANDBOX_ID, message_id=msg_id)
print(eml)

headers = get_mail_headers(sandbox_id=SANDBOX_ID, message_id=msg_id)
print(headers)
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
ACCOUNT_ID = os.environ["MAILTRAP_ACCOUNT_ID"]

client = mt.MailtrapClient(token=API_KEY, account_id=ACCOUNT_ID)
projects_api = client.testing_api.projects
projects_api = client.sandbox_api.projects
Comment thread
Rabsztok marked this conversation as resolved.
Resolved


def list_projects() -> list[Project]:
Expand Down
Loading
Loading