Skip to content

Commit

Permalink
feat: Support from attr (#100)
Browse files Browse the repository at this point in the history
  • Loading branch information
drish authored May 24, 2024
1 parent 3464c18 commit bdef6b2
Show file tree
Hide file tree
Showing 14 changed files with 65 additions and 16 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import resend
resend.api_key = "re_yourkey"

params: resend.Emails.SendParams = {
"from_": "[email protected]",
"from": "[email protected]",
"to": ["[email protected]"],
"subject": "hi",
"html": "<strong>hello, world!</strong>",
Expand Down
4 changes: 2 additions & 2 deletions examples/batch_email_send.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@

params: List[resend.Emails.SendParams] = [
{
"from_": "[email protected]",
"from": "[email protected]",
"to": ["[email protected]"],
"subject": "hey",
"html": "<strong>hello, world!</strong>",
},
{
"from_": "[email protected]",
"from": "[email protected]",
"to": ["[email protected]"],
"subject": "hello",
"html": "<strong>hello, world!</strong>",
Expand Down
2 changes: 1 addition & 1 deletion examples/simple_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
raise EnvironmentError("RESEND_API_KEY is missing")

params: resend.Emails.SendParams = {
"from_": "[email protected]",
"from": "[email protected]",
"to": ["[email protected]"],
"subject": "hi",
"html": "<strong>hello, world!</strong>",
Expand Down
2 changes: 1 addition & 1 deletion examples/with_attachments.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

# Define the email parameters
params: resend.Emails.SendParams = {
"from_": "[email protected]",
"from": "[email protected]",
"to": ["[email protected]"],
"subject": "hi",
"html": "<strong>hello, world!</strong>",
Expand Down
2 changes: 1 addition & 1 deletion examples/with_b64_attachments.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

# Email params
params: resend.Emails.SendParams = {
"from_": "[email protected]",
"from": "[email protected]",
"to": ["[email protected]"],
"subject": "hello with base64 attachments",
"html": "<strong>hello, world!</strong>",
Expand Down
2 changes: 1 addition & 1 deletion examples/with_exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
raise EnvironmentError("RESEND_API_KEY is missing")

params: resend.Emails.SendParams = {
"from_": "[email protected]",
"from": "[email protected]",
"to": ["invalid"],
"subject": "hi",
"html": "<strong>hello, world!</strong>",
Expand Down
2 changes: 1 addition & 1 deletion examples/with_html_file_as_b64_attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

# Email params
params: resend.Emails.SendParams = {
"from_": "[email protected]",
"from": "[email protected]",
"to": ["[email protected]"],
"subject": "hello with base64 attachments",
"html": "<strong>hello, world!</strong>",
Expand Down
1 change: 1 addition & 0 deletions resend/emails/_batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def send(cls, params: List[Emails.SendParams]) -> List[Email]:
path = "/emails/batch"

# loop through the list of params and replace "from_" or "sender" with "from"
# if they're present
replaced_params = [
replace_params(cast(Dict[Any, Any], param)) for param in params
]
Expand Down
4 changes: 2 additions & 2 deletions resend/emails/_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ def new_from_request(val: Dict[Any, Any]) -> "Email":
email = Email(
id=val["id"] if "id" in val else "",
to=val["to"] if "to" in val else "",
# we set sender as the value from "from" here
# because "from" is a reserved keyword in python
# from is a reserved keyword in python
# so we set both from_ and sender here
from_=val["from"] if "from" in val else "",
sender=val["from"] if "from" in val else "",
created_at=val["created_at"] if "created_at" in val else "",
Expand Down
19 changes: 18 additions & 1 deletion resend/emails/_emails.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,23 @@
from resend.emails._tag import Tag
from resend.utils import replace_params

SendParamsFrom = TypedDict(
"SendParamsFrom",
{
"from": str,
"to": Union[str, List[str]],
"subject": str,
"bcc": NotRequired[Union[List[str], str]],
"cc": NotRequired[Union[List[str], str]],
"reply_to": NotRequired[Union[List[str], str]],
"html": NotRequired[str],
"text": NotRequired[str],
"headers": NotRequired[Dict[str, str]],
"attachments": NotRequired[List[Attachment]],
"tags": NotRequired[List[Tag]],
},
)


class SendParamsDefault(TypedDict):
to: Union[str, List[str]]
Expand Down Expand Up @@ -71,7 +88,7 @@ class SendParamsSender(SendParamsDefault):


class Emails:
SendParams = Union[SendParamsFrom_, SendParamsSender]
SendParams = Union[SendParamsFrom, SendParamsFrom_, SendParamsSender]

@classmethod
def send(cls, params: SendParams) -> Email:
Expand Down
1 change: 0 additions & 1 deletion resend/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ def perform(self) -> Any:
requests.HTTPError: If the request fails
"""
resp = self.make_request(url=f"{resend.api_url}{self.path}")

# delete calls do not return a body
if resp.text == "" and resp.status_code == 200:
return None
Expand Down
8 changes: 6 additions & 2 deletions resend/utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from typing import Any, Dict


# we need this workaround here because "from" is a reserved keyword
# in python, so accept either "sender" or "from_" in the SendParams class
# this is a backwards compatibility function that is here because
# this lib v1.0.0 was initially released with only
# "sender" and "from_" as supported attributes.
# here because "from" is a reserved keyword
def replace_params(params: Dict[Any, Any]) -> Dict[Any, Any]:
if "from" in params:
return params
if "from_" in params:
params["from"] = params["from_"]
params.pop("from_")
Expand Down
4 changes: 2 additions & 2 deletions tests/batch_emails_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ def mock_json() -> Dict[Any, Any]:

params: List[resend.Emails.SendParams] = [
{
"from_": "[email protected]",
"from": "[email protected]",
"to": ["[email protected]"],
"subject": "hey",
"html": "<strong>hello, world!</strong>",
},
{
"from_": "[email protected]",
"from": "[email protected]",
"to": ["[email protected]"],
"subject": "hello",
"html": "<strong>hello, world!</strong>",
Expand Down
28 changes: 28 additions & 0 deletions tests/emails_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,34 @@


class TestResendEmail(unittest.TestCase):

def test_email_send_with_from(self) -> None:
resend.api_key = "re_123"

patcher = patch("resend.Request.make_request")
mock = patcher.start()
mock.status_code = 200
m = MagicMock()
m.status_code = 200

def mock_json() -> Dict[Any, Any]:
return {
"id": "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794",
}

m.json = mock_json
mock.return_value = m

params: resend.Emails.SendParams = {
"to": "[email protected]",
"from": "[email protected]",
"subject": "subject",
"html": "html",
}
email: resend.Email = resend.Emails.send(params)
assert email.id == "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794"
patcher.stop()

def test_email_send_with_sender(self) -> None:
resend.api_key = "re_123"

Expand Down

0 comments on commit bdef6b2

Please sign in to comment.