Skip to content
Merged
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
62 changes: 62 additions & 0 deletions examples/email_templates/templates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from typing import Optional

import mailtrap as mt
from mailtrap.models.common import DeletedObject
from mailtrap.models.templates import EmailTemplate

API_TOKEN = "YOU_API_TOKEN"
ACCOUNT_ID = "YOU_ACCOUNT_ID"

client = mt.MailtrapClient(token=API_TOKEN, account_id=ACCOUNT_ID)
templates_api = client.email_templates_api.templates


def list_templates() -> list[EmailTemplate]:
return templates_api.get_list()


def create_template(
name: str,
subject: str,
category: str,
body_text: Optional[str] = None,
body_html: Optional[str] = None,
) -> EmailTemplate:
params = mt.CreateEmailTemplateParams(
name=name,
subject=subject,
category=category,
body_text=body_text,
body_html=body_html,
)
return templates_api.create(params)


def get_template(template_id: str) -> EmailTemplate:
return templates_api.get_by_id(template_id)


def update_template(
template_id: str,
name: Optional[str] = None,
subject: Optional[str] = None,
category: Optional[str] = None,
body_text: Optional[str] = None,
body_html: Optional[str] = None,
) -> EmailTemplate:
params = mt.UpdateEmailTemplateParams(
name=name,
subject=subject,
category=category,
body_text=body_text,
body_html=body_html,
)
return templates_api.update(template_id, params)


def delete_template(template_id: str) -> DeletedObject:
return templates_api.delete(template_id)


if __name__ == "__main__":
print(list_templates())
2 changes: 2 additions & 0 deletions mailtrap/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@
from .models.mail import Disposition
from .models.mail import Mail
from .models.mail import MailFromTemplate
from .models.templates import CreateEmailTemplateParams
from .models.templates import UpdateEmailTemplateParams
43 changes: 43 additions & 0 deletions mailtrap/api/resources/templates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from mailtrap.http import HttpClient
from mailtrap.models.common import DeletedObject
from mailtrap.models.templates import CreateEmailTemplateParams
from mailtrap.models.templates import EmailTemplate
from mailtrap.models.templates import UpdateEmailTemplateParams


class TemplatesApi:
def __init__(self, client: HttpClient, account_id: str) -> None:
self._account_id = account_id
self._client = client

def get_list(self) -> list[EmailTemplate]:
response = self._client.get(f"/api/accounts/{self._account_id}/email_templates")
return [EmailTemplate(**template) for template in response]

def get_by_id(self, template_id: int) -> EmailTemplate:
response = self._client.get(
f"/api/accounts/{self._account_id}/email_templates/{template_id}"
)
return EmailTemplate(**response)

def create(self, template_params: CreateEmailTemplateParams) -> EmailTemplate:
response = self._client.post(
f"/api/accounts/{self._account_id}/email_templates",
json={"email_template": template_params.api_data},
)
return EmailTemplate(**response)

def update(
self, template_id: int, template_params: UpdateEmailTemplateParams
) -> EmailTemplate:
response = self._client.patch(
f"/api/accounts/{self._account_id}/email_templates/{template_id}",
json={"email_template": template_params.api_data},
)
return EmailTemplate(**response)

def delete(self, template_id: int) -> DeletedObject:
self._client.delete(
f"/api/accounts/{self._account_id}/email_templates/{template_id}"
)
return DeletedObject(template_id)
12 changes: 12 additions & 0 deletions mailtrap/api/templates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from mailtrap.api.resources.templates import TemplatesApi
from mailtrap.http import HttpClient


class EmailTemplatesApi:
def __init__(self, client: HttpClient, account_id: str) -> None:
self._account_id = account_id
self._client = client

@property
def templates(self) -> TemplatesApi:
return TemplatesApi(account_id=self._account_id, client=self._client)
9 changes: 9 additions & 0 deletions mailtrap/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from pydantic import TypeAdapter

from mailtrap.api.sending import SendingApi
from mailtrap.api.templates import EmailTemplatesApi
from mailtrap.api.testing import TestingApi
from mailtrap.config import BULK_HOST
from mailtrap.config import GENERAL_HOST
Expand Down Expand Up @@ -54,6 +55,14 @@ def testing_api(self) -> TestingApi:
client=HttpClient(host=GENERAL_HOST, headers=self.headers),
)

@property
def email_templates_api(self) -> EmailTemplatesApi:
self._validate_account_id()
return EmailTemplatesApi(
account_id=cast(str, self.account_id),
client=HttpClient(host=GENERAL_HOST, headers=self.headers),
)

@property
def sending_api(self) -> SendingApi:
http_client = HttpClient(host=self._sending_api_host, headers=self.headers)
Expand Down
4 changes: 4 additions & 0 deletions mailtrap/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ def _url(self, path: str) -> str:
def _process_response(self, response: Response) -> Any:
if not response.ok:
self._handle_failed_response(response)

if not response.content.strip():
return None

return response.json()

def _handle_failed_response(self, response: Response) -> NoReturn:
Expand Down
4 changes: 2 additions & 2 deletions mailtrap/models/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
from pydantic import TypeAdapter
from pydantic.dataclasses import dataclass

T = TypeVar("T", bound="RequestModel")
T = TypeVar("T", bound="RequestParams")


@dataclass
class RequestModel:
class RequestParams:
@property
def api_data(self: T) -> dict[str, Any]:
return cast(
Expand Down
4 changes: 2 additions & 2 deletions mailtrap/models/mail/address.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

from pydantic.dataclasses import dataclass

from mailtrap.models.common import RequestModel
from mailtrap.models.common import RequestParams


@dataclass
class Address(RequestModel):
class Address(RequestParams):
email: str
name: Optional[str] = None
4 changes: 2 additions & 2 deletions mailtrap/models/mail/attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from pydantic import field_serializer
from pydantic.dataclasses import dataclass

from mailtrap.models.common import RequestModel
from mailtrap.models.common import RequestParams


class Disposition(str, Enum):
Expand All @@ -15,7 +15,7 @@ class Disposition(str, Enum):


@dataclass
class Attachment(RequestModel):
class Attachment(RequestParams):
content: bytes
filename: str
disposition: Optional[Disposition] = None
Expand Down
4 changes: 2 additions & 2 deletions mailtrap/models/mail/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
from pydantic import Field
from pydantic.dataclasses import dataclass

from mailtrap.models.common import RequestModel
from mailtrap.models.common import RequestParams
from mailtrap.models.mail.address import Address
from mailtrap.models.mail.attachment import Attachment


@dataclass
class BaseMail(RequestModel):
class BaseMail(RequestParams):
sender: Address = Field(..., serialization_alias="from")
to: list[Address] = Field(...)
cc: Optional[list[Address]] = None
Expand Down
49 changes: 49 additions & 0 deletions mailtrap/models/templates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from typing import Optional

from pydantic.dataclasses import dataclass

from mailtrap.models.common import RequestParams


@dataclass
class CreateEmailTemplateParams(RequestParams):
name: str
subject: str
category: str
body_text: Optional[str] = None
body_html: Optional[str] = None


@dataclass
class UpdateEmailTemplateParams(RequestParams):
name: Optional[str] = None
subject: Optional[str] = None
category: Optional[str] = None
body_text: Optional[str] = None
body_html: Optional[str] = None

def __post_init__(self) -> None:
if all(
value is None
for value in [
self.name,
self.subject,
self.category,
self.body_text,
self.body_html,
]
):
raise ValueError("At least one field must be provided for update action")


@dataclass
class EmailTemplate:
id: int
name: str
uuid: str
category: str
subject: str
body_text: Optional[str]
body_html: Optional[str]
created_at: str
updated_at: str
Loading
Loading