8000 Fix issue #24: Add batch_send method to SendingApi, add models by Ihor-Bilous · Pull Request #47 · mailtrap/mailtrap-python · GitHub
[go: up one dir, main page]

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
45 changes: 42 additions & 3 deletions examples/sending.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,54 @@
},
)

batch_mail = mt.BatchSendEmailParams(
base=mt.BatchMail(
sender=mt.Address(email="<SENDER_EMAIL>", name="<SENDER_NAME>"),
subject="You are awesome!",
text="Congrats for sending test email with Mailtrap!",
category="Integration Test",
),
requests=[
mt.BatchEmailRequest(
to=[mt.Address(email="<RECEIVER_EMAIL>")],
),
],
)

batch_mail_from_template = mt.BatchSendEmailParams(
base=mt.BatchMailFromTemplate(
sender=mt.Address(email="<SENDER_EMAIL>", name="<SENDER_NAME>"),
template_uuid="<YOUR_TEMPLATE_UUID>",
template_variables={
"company_info_name": "Test_Company_info_name",
"name": "Test_Name",
"company_info_address": "Test_Company_info_address",
"company_info_city": "Test_Company_info_city",
"company_info_zip_code": "Test_Company_info_zip_code",
"company_info_country": "Test_Company_info_country",
},
),
requests=[
mt.BatchEmailRequest(
to=[mt.Address(email="<RECEIVER_EMAIL>")],
subject="You are awesome!",
text="Congrats for sending test email with Mailtrap!",
category="Integration Test",
),
],
)


def send(client: mt.MailtrapClient, mail: mt.BaseMail) -> mt.SEND_ENDPOINT_RESPONSE:
return client.send(mail)


def batch_send(client: mt.MailtrapClient, mail: mt.BaseMail) -> mt.SEND_ENDPOINT_RESPONSE:
# will be added soon
pass
def batch_send(
client: mt.MailtrapClient, mail: mt.BatchSendEmailParams
) -> mt.BATCH_SEND_ENDPOINT_RESPONSE:
return client.batch_send(mail=mail)


if __name__ == "__main__":
print(send(default_client, mail))
print(batch_send(default_client, batch_mail))
5 changes: 5 additions & 0 deletions mailtrap/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .client import BATCH_SEND_ENDPOINT_RESPONSE
from .client import SEND_ENDPOINT_RESPONSE
from .client import MailtrapClient
from .exceptions import APIError
Expand All @@ -15,6 +16,10 @@
from .models.mail import Address
from .models.mail import Attachment
from .models.mail import BaseMail
from .models.mail import BatchEmailRequest
from .models.mail import BatchMail
from .models.mail import BatchMailFromTemplate
from .models.mail import BatchSendEmailParams
from .models.mail import Disposition
from .models.mail import Mail
from .models.mail import MailFromTemplate
Expand Down
29 changes: 21 additions & 8 deletions mailtrap/api/sending.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,36 @@
from typing import Optional

from mailtrap.http import HttpClient
from mailtrap.models.mail.base import BaseMail
from mailtrap.models.mail.base import SendingMailResponse
from mailtrap.models.mail import BaseMail
from mailtrap.models.mail import SendingMailResponse
from mailtrap.models.mail.batch_mail import BatchSendEmailParams
from mailtrap.models.mail.batch_mail import BatchSendResponse


class SendingApi:
def __init__(self, client: HttpClient, inbox_id: Optional[str] = None) -> None:
self._inbox_id = inbox_id
self._client = client

@property
def _api_url(self) -> str:
url = "/api/send"
def _get_api_url(self, base_url: str) -> str:
if self._inbox_id:
return f"{url}/{self._inbox_id}"
return url
return f"{base_url}/{self._inbox_id}"
return base_url

def send(self, mail: BaseMail) -> SendingMailResponse:
"""Send email (text, html, text&html, templates)."""
response = self._client.post(self._api_url, json=mail.api_data)
response = self._client.post(self._get_api_url("/api/send"), json=mail.api_data)
return SendingMailResponse(**response)

def batch_send(self, mail: BatchSendEmailParams) -> BatchSendResponse:
"""
Batch send email (text, html, text&html, templates). Please note that
the endpoint will return a 200-level http status, even when sending
for individual messages may fail. Users of this endpoint should check
the success and errors for each message in the response (the results
are ordered the same as the original messages - requests). Please note
that the endpoint accepts up to 500 messages per API call, and up to 50 MB
payload size, including attachments.
"""
response = self._client.post(self._get_api_url("/api/batch"), json=mail.api_data)
return BatchSendResponse(**response)
14 changes: 13 additions & 1 deletion mailtrap/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@
from mailtrap.exceptions import ClientConfigurationError
from mailtrap.http import HttpClient
from mailtrap.models.mail import BaseMail
from mailtrap.models.mail.base import SendingMailResponse
from mailtrap.models.mail import BatchSendResponse
from mailtrap.models.mail import SendingMailResponse
from mailtrap.models.mail.batch_mail import BatchSendEmailParams

SEND_ENDPOINT_RESPONSE = dict[str, Union[bool, list[str]]]
BATCH_SEND_ENDPOINT_RESPONSE = dict[
str, Union[bool, list[str], list[dict[str, Union[bool, list[str]]]]]
]


class MailtrapClient:
Expand Down Expand Up @@ -93,6 +98,13 @@ def send(self, mail: BaseMail) -> SEND_ENDPOINT_RESPONSE:
TypeAdapter(SendingMailResponse).dump_python(sending_response),
)

def batch_send(self, mail: BatchSendEmailParams) -> BATCH_SEND_ENDPOINT_RESPONSE:
batch_sending_response = self.sending_api.batch_send(mail)
return cast(
BATCH_SEND_ENDPOINT_RESPONSE,
TypeAdapter(BatchSendResponse).dump_python(batch_sending_response),
)

@property
def base_url(self) -> str:
warnings.warn(
Expand Down
20 changes: 17 additions & 3 deletions mailtrap/models/mail/__init__.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
from mailtrap.models.mail.address import Address
from mailtrap.models.mail.attachment import Attachment
from mailtrap.models.mail.attachment import Disposition
from mailtrap.models.mail.base import BaseMail
from mailtrap.models.mail.from_template import MailFromTemplate
from mailtrap.models.mail.batch_mail import BaseBatchMail
from mailtrap.models.mail.batch_mail import BatchEmailRequest
from mailtrap.models.mail.batch_mail import BatchMail
from mailtrap.models.mail.batch_mail import BatchMailFromTemplate
from mailtrap.models.mail.batch_mail import BatchSendEmailParams
from mailtrap.models.mail.batch_mail import BatchSendResponse
from mailtrap.models.mail.mail import BaseMail
from mailtrap.models.mail.mail import Mail
from mailtrap.models.mail.mail import MailFromTemplate
from mailtrap.models.mail.mail import SendingMailResponse

__all__ = [
"Address",
"Attachment",
"Disposition",
"BaseBatchMail",
"BaseMail",
"BatchEmailRequest",
"BatchMail",
"BatchMailFromTemplate",
"BatchSendEmailParams",
"BatchSendResponse",
"Disposition",
"Mail",
"MailFromTemplate",
"SendingMailResponse",
]
9E81 26 changes: 0 additions & 26 deletions mailtrap/models/mail/base.py

This file was deleted.

69 changes: 69 additions & 0 deletions mailtrap/models/mail/batch_mail.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from typing import Any
from typing import Optional
from typing import Union

from pydantic import Field
from pydantic.dataclasses import dataclass

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


@dataclass
class BaseBatchMail(RequestParams):
sender: Address = Field(..., serialization_alias="from")
attachments: Optional[list[Attachment]] = None
headers: Optional[dict[str, str]] = None
custom_variables: Optional[dict[str, Any]] = None
reply_to: Optional[Address] = None


@dataclass
class BatchMail(BaseBatchMail):
subject: str = Field(...) # type:ignore
text: Optional[str] = None
html: Optional[str] = None
category: Optional[str] = None


@dataclass
class BatchMailFromTemplate(BaseBatchMail):
template_uuid: str = Field(...) # type:ignore
6D3F template_variables: Optional[dict[str, Any]] = None


@dataclass
class BatchEmailRequest(BaseBatchMail):
to: list[Address] = Field(...) # type:ignore
sender: Optional[Address] = Field(
None, serialization_alias="from"
) # type: ignore[assignment]
cc: Optional[list[Address]] = None
bcc: Optional[list[Address]] = None
subject: Optional[str] = None
text: Optional[str] = None
html: Optional[str] = None
category: Optional[str] = None
template_uuid: Optional[str] = None
template_variables: Optional[dict[str, Any]] = None


@dataclass
class BatchSendEmailParams(RequestParams):
base: Union[BatchMail, BatchMailFromTemplate]
requests: list[BatchEmailRequest]


@dataclass
class BatchSendResponseItem:
success: bool
message_ids: Optional[list[str]] = None
errors: Optional[list[str]] = None


@dataclass
class BatchSendResponse:
success: bool
responses: list[BatchSendResponseItem]
errors: Optional[list[str]] = None
13 changes: 0 additions & 13 deletions mailtrap/models/mail/from_template.py

This file was deleted.

29 changes: 28 additions & 1 deletion mailtrap/models/mail/mail.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
from typing import Any
from typing import Optional

from pydantic import Field
from pydantic.dataclasses import dataclass

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


@dataclass
class BaseMail(RequestParams):
to: list[Address]
sender: Address = Field(..., serialization_alias="from")
cc: Optional[list[Address]] = None
bcc: Optional[list[Address]] = None
attachments: Optional[list[Attachment]] = None
headers: Optional[dict[str, str]] = None
custom_variables: Optional[dict[str, Any]] = None
reply_to: Optional[Address] = None


@dataclass
Expand All @@ -12,3 +27,15 @@ class Mail(BaseMail):
text: Optional[str] = None
html: Optional[str] = None
category: Optional[str] = None


@dataclass
class MailFromTemplate(BaseMail):
template_uuid: str = Field(...) # type:ignore
template_variables: Optional[dict[str, Any]] = None


@dataclass
class SendingMailResponse:
success: bool
message_ids: list[str]
Loading
Loading
0