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
23 changes: 23 additions & 0 deletions examples/audiences.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import os

import resend

if not os.environ["RESEND_API_KEY"]:
raise EnvironmentError("RESEND_API_KEY is missing")


audience = resend.Audiences.create(
{
"name": "New Audience from Python SDK",
}
)
print(audience)

aud = resend.Audiences.get(audience["id"])
print(aud)

audiences = resend.Audiences.list()
print(audiences)

rmed = resend.Audiences.remove(audience["id"])
print(rmed)
7 changes: 4 additions & 3 deletions examples/with_b64_attachments.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import base64
import os

import resend
import base64

if not os.environ["RESEND_API_KEY"]:
raise EnvironmentError("RESEND_API_KEY is missing")
Expand All @@ -10,7 +11,7 @@
).read()

b64 = base64.b64encode(f)
b64_str = b64.decode('utf-8')
b64_str = b64.decode("utf-8")

params = {
"from": "onboarding@resend.dev",
Expand All @@ -21,4 +22,4 @@
}

email = resend.Emails.send(params)
print(email)
print(email)
7 changes: 4 additions & 3 deletions examples/with_html_file_as_b64_attachment.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import base64
import os

import resend
import base64

if not os.environ["RESEND_API_KEY"]:
raise EnvironmentError("RESEND_API_KEY is missing")
Expand All @@ -10,7 +11,7 @@
).read()

b64 = base64.b64encode(f)
b64_str = b64.decode('utf-8')
b64_str = b64.decode("utf-8")

params = {
"from": "onboarding@resend.dev",
Expand All @@ -21,4 +22,4 @@
}

email = resend.Emails.send(params)
print(email)
print(email)
14 changes: 12 additions & 2 deletions resend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

from .api import Resend
from .api_keys import ApiKeys
from .audiences import Audiences
from .batch import Batch
from .domains import Domains
from .emails import Emails
from .batch import Batch
from .request import Request
from .version import get_version

Expand All @@ -15,4 +16,13 @@
# API resources
from .emails import Emails # noqa

__all__ = ["get_version", "Resend", "Request", "Emails", "ApiKeys", "Domains", "Batch"]
__all__ = [
"get_version",
"Resend",
"Request",
"Emails",
"ApiKeys",
"Domains",
"Batch",
"Audiences",
]
5 changes: 3 additions & 2 deletions resend/api.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from warnings import warn
from typing import Dict, List
from warnings import warn

import resend

Expand All @@ -25,7 +25,8 @@ def send_email(
):
warn(
"[DEPRECATION]: method `send_email` is deprecated. Use resend.Emails.send() instead",
DeprecationWarning)
DeprecationWarning,
)
return resend.Emails.send(
{
"from": sender,
Expand Down
31 changes: 31 additions & 0 deletions resend/audiences.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from typing import Dict

from resend import request


class Audiences:
"""Audiences API Wrapper"""

@classmethod
# https://resend.com/docs/api-reference/audiences/create-audience
def create(cls, params={}) -> Dict:
path = "/audiences"
return request.Request(path=path, params=params, verb="post").perform()

@classmethod
# https://resend.com/docs/api-reference/audiences/list-audiences
def list(cls) -> Dict:
path = "/audiences/"
return request.Request(path=path, params={}, verb="get").perform()

@classmethod
# https://resend.com/docs/api-reference/audiences/get-audience
def get(cls, id) -> Dict:
path = f"/audiences/{id}"
return request.Request(path=path, params={}, verb="get").perform()

@classmethod
# https://resend.com/docs/api-reference/audiences/delete-audience
def remove(cls, id="") -> Dict:
path = f"/audiences/{id}"
return request.Request(path=path, params={}, verb="delete").perform()
2 changes: 1 addition & 1 deletion resend/batch.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List, Dict
from typing import Dict, List

from resend import request

Expand Down
121 changes: 121 additions & 0 deletions tests/audiences_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import unittest
from unittest.mock import MagicMock, patch

import resend

# flake8: noqa


class TestResendAudiences(unittest.TestCase):
def test_audiences_create(self):
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():
return {
"object": "audience",
"id": "78261eea-8f8b-4381-83c6-79fa7120f1cf",
"name": "Registered Users",
}

m.json = mock_json
mock.return_value = m

params = {
"name": "Python SDK Audience",
}
audience = resend.Audiences.create(params)
assert audience["id"] == "78261eea-8f8b-4381-83c6-79fa7120f1cf"
assert audience["name"] == "Registered Users"
assert audience["object"] == "audience"

patcher.stop()

def test_audiences_get(self):
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():
return {
"object": "audience",
"id": "78261eea-8f8b-4381-83c6-79fa7120f1cf",
"name": "Registered Users",
"created_at": "2023-10-06T22:59:55.977Z",
}

m.json = mock_json
mock.return_value = m

audience = resend.Audiences.list()
assert audience["object"] == "audience"
assert audience["id"] == "78261eea-8f8b-4381-83c6-79fa7120f1cf"
assert audience["name"] == "Registered Users"

patcher.stop()

def test_audiences_remove(self):
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():
return {
"object": "audience",
"id": "78261eea-8f8b-4381-83c6-79fa7120f1cf",
"deleted": True,
}

m.json = mock_json
mock.return_value = m

rmed = resend.Audiences.remove("78261eea-8f8b-4381-83c6-79fa7120f1cf")
assert rmed["object"] == "audience"
assert rmed["id"] == "78261eea-8f8b-4381-83c6-79fa7120f1cf"
assert rmed["deleted"] is True

patcher.stop()

def test_audiences_list(self):
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():
return {
"object": "list",
"data": [
{
"id": "78261eea-8f8b-4381-83c6-79fa7120f1cf",
"name": "Registered Users",
"created_at": "2023-10-06T22:59:55.977Z",
}
],
}

m.json = mock_json
mock.return_value = m

audience = resend.Audiences.list()
assert audience["object"] == "list"
assert audience["data"][0]["id"] == "78261eea-8f8b-4381-83c6-79fa7120f1cf"
assert audience["data"][0]["name"] == "Registered Users"

patcher.stop()
30 changes: 13 additions & 17 deletions tests/batch_emails_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,31 @@ def test_batch_email_send(self):

def mock_json():
return {
"data": [
{
"id": "ae2014de-c168-4c61-8267-70d2662a1ce1"
},
{
"id": "faccb7a5-8a28-4e9a-ac64-8da1cc3bc1cb"
}
]
"data": [
{"id": "ae2014de-c168-4c61-8267-70d2662a1ce1"},
{"id": "faccb7a5-8a28-4e9a-ac64-8da1cc3bc1cb"},
]
}

m.json = mock_json
mock.return_value = m

params = [
{
"from": "from@resend.dev",
"to": ["to@resend.dev"],
"subject": "hey",
"html": "<strong>hello, world!</strong>",
"from": "from@resend.dev",
"to": ["to@resend.dev"],
"subject": "hey",
"html": "<strong>hello, world!</strong>",
},
{
"from": "from@resend.dev",
"to": ["to@resend.dev"],
"subject": "hello",
"html": "<strong>hello, world!</strong>",
"from": "from@resend.dev",
"to": ["to@resend.dev"],
"subject": "hello",
"html": "<strong>hello, world!</strong>",
},
]
emails = resend.Batch.send(params)
assert len(emails["data"]) == 2
assert emails["data"][0]["id"] == "ae2014de-c168-4c61-8267-70d2662a1ce1"
assert emails["data"][1]["id"] == "faccb7a5-8a28-4e9a-ac64-8da1cc3bc1cb"
patcher.stop()
patcher.stop()