Skip to content

Commit 0b85867

Browse files
committed
fix conflicts
2 parents b8021b7 + f10bf39 commit 0b85867

96 files changed

Lines changed: 8223 additions & 523 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ jobs:
99
matrix:
1010
python-version: ["3.8", "3.9", "3.10", "3.11"]
1111
steps:
12-
- uses: actions/checkout@v2
12+
- uses: actions/checkout@v6
1313
- name: Set up Python ${{ matrix.python-version }}
14-
uses: actions/setup-python@v2
14+
uses: actions/setup-python@v6
1515
with:
1616
python-version: ${{ matrix.python-version }}
1717
- name: Install dependencies
@@ -28,17 +28,17 @@ jobs:
2828
os: [ubuntu-latest]
2929
python-version: ["3.8", "3.9", "3.10", "3.11"]
3030
steps:
31-
- uses: actions/checkout@v2
31+
- uses: actions/checkout@v6
3232
- name: Set up Python ${{ matrix.python-version }}
33-
uses: actions/setup-python@v2
33+
uses: actions/setup-python@v6
3434
with:
3535
python-version: ${{ matrix.python-version }}
3636
- name: Install dependencies
3737
run: pip install tox
3838
- name: Test with pytest and generate coverage file
3939
run: tox -e py
4040
- name: Upload coverage report to codecov
41-
uses: codecov/codecov-action@v1
41+
uses: codecov/codecov-action@v5
4242
if: success()
4343
with:
4444
file: coverage.xml

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM python:3.13.4
1+
FROM python:3.14.3
22

33
RUN pip install --upgrade pip
44

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ params: resend.Emails.SendParams = {
5252
],
5353
}
5454

55-
email: resend.Email = resend.Emails.send(params)
55+
email: resend.Emails.SendResponse = resend.Emails.send(params)
5656
print(email)
5757
```
5858

examples/api_keys.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,31 @@
1010
"name": "example.com",
1111
}
1212

13-
key: resend.ApiKey = resend.ApiKeys.create(params=create_params)
13+
created_key: resend.ApiKeys.CreateApiKeyResponse = resend.ApiKeys.create(
14+
params=create_params
15+
)
1416
print("Created new api key")
15-
print(f"Key id: {key['id']} and token: {key['token']}")
17+
print(f"Key id: {created_key['id']} and token: {created_key['token']}")
1618

1719
keys: resend.ApiKeys.ListResponse = resend.ApiKeys.list()
1820
for key in keys["data"]:
1921
print(key["id"])
2022
print(key["name"])
2123
print(key["created_at"])
2224

23-
if len(keys) > 0:
25+
print("\n--- Using pagination parameters ---")
26+
if keys["data"]:
27+
paginated_params: resend.ApiKeys.ListParams = {
28+
"limit": 8,
29+
"after": keys["data"][0]["id"],
30+
}
31+
paginated_keys: resend.ApiKeys.ListResponse = resend.ApiKeys.list(
32+
params=paginated_params
33+
)
34+
print(f"Retrieved {len(paginated_keys['data'])} keys with pagination")
35+
print(f"Has more keys: {paginated_keys['has_more']}")
36+
else:
37+
print("No keys available for pagination example")
38+
39+
if len(keys["data"]) > 0:
2440
resend.ApiKeys.remove(api_key_id=keys["data"][0]["id"])

examples/api_keys_async.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ async def main() -> None:
1616
"name": "example.com",
1717
}
1818

19-
key: resend.ApiKey = await resend.ApiKeys.create_async(params=create_params)
19+
key = await resend.ApiKeys.create_async(params=create_params)
2020
print("Created new api key")
2121
print(f"Key id: {key['id']} and token: {key['token']}")
2222

2323
keys: resend.ApiKeys.ListResponse = await resend.ApiKeys.list_async()
24-
for key in keys["data"]:
25-
print(key["id"])
26-
print(key["name"])
27-
print(key["created_at"])
24+
for k in keys["data"]:
25+
print(k["id"])
26+
print(k["name"])
27+
print(k["created_at"])
2828

2929
if len(keys["data"]) > 0:
3030
await resend.ApiKeys.remove_async(api_key_id=keys["data"][0]["id"])

examples/audiences.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
create_params: resend.Audiences.CreateParams = {
1111
"name": "New Audience from Python SDK",
1212
}
13-
audience: resend.Audience = resend.Audiences.create(create_params)
13+
audience: resend.Audiences.CreateAudienceResponse = resend.Audiences.create(
14+
create_params
15+
)
1416
print(f"Created audience: {audience['id']}")
1517
print(audience)
1618

@@ -19,7 +21,24 @@
1921

2022
audiences: resend.Audiences.ListResponse = resend.Audiences.list()
2123
print("List of audiences:", [a["id"] for a in audiences["data"]])
24+
print(f"Has more audiences: {audiences['has_more']}")
2225

23-
rmed: resend.Audience = resend.Audiences.remove(id=audience["id"])
24-
print(f"Deleted audience")
26+
print("\n--- Using pagination parameters ---")
27+
if audiences["data"]:
28+
paginated_params: resend.Audiences.ListParams = {
29+
"limit": 5,
30+
"after": audiences["data"][0]["id"],
31+
}
32+
paginated_audiences: resend.Audiences.ListResponse = resend.Audiences.list(
33+
params=paginated_params
34+
)
35+
print(f"Retrieved {len(paginated_audiences['data'])} audiences with pagination")
36+
print(f"Has more audiences: {paginated_audiences['has_more']}")
37+
else:
38+
print("No audiences available for pagination example")
39+
40+
rmed: resend.Audiences.RemoveAudienceResponse = resend.Audiences.remove(
41+
id=audience["id"]
42+
)
43+
print(f"Deleted audience with ID: {audience['id']}")
2544
print(rmed)

examples/audiences_async.py

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import asyncio
22
import os
3-
from typing import List
43

54
import resend
65

@@ -12,21 +11,25 @@
1211

1312

1413
async def main() -> None:
15-
create_params: resend.Audiences.CreateParams = {
16-
"name": "New Audience from Python SDK (Async)",
14+
create_params: resend.Segments.CreateParams = {
15+
"name": "New Segment from Python SDK (Async)",
1716
}
18-
audience: resend.Audience = await resend.Audiences.create_async(create_params)
19-
print(f"Created audience: {audience['id']}")
20-
print(audience)
21-
22-
aud: resend.Audience = await resend.Audiences.get_async(audience["id"])
23-
print("Retrieved audience: ", aud)
24-
25-
audiences: resend.Audiences.ListResponse = await resend.Audiences.list_async()
26-
print("List of audiences:", [a["id"] for a in audiences["data"]])
27-
28-
rmed: resend.Audience = await resend.Audiences.remove_async(id=audience["id"])
29-
print(f"Deleted audience")
17+
segment: resend.Segments.CreateSegmentResponse = await resend.Segments.create_async(
18+
create_params
19+
)
20+
print(f"Created segment: {segment['id']}")
21+
print(segment)
22+
23+
seg: resend.Segment = await resend.Segments.get_async(segment["id"])
24+
print("Retrieved segment: ", seg)
25+
26+
segments: resend.Segments.ListResponse = await resend.Segments.list_async()
27+
print("List of segments:", [s["id"] for s in segments["data"]])
28+
29+
rmed: resend.Segments.RemoveSegmentResponse = await resend.Segments.remove_async(
30+
id=segment["id"]
31+
)
32+
print("Deleted segment")
3033
print(rmed)
3134

3235

examples/batch_email_send.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,45 @@
4949
print("Failed to send batch emails")
5050
print(f"Error: {err}")
5151
exit(1)
52+
53+
try:
54+
# Send batch emails with permissive validation mode
55+
print("sending with permissive validation mode")
56+
57+
# Example with some invalid emails to demonstrate error handling
58+
mixed_params: List[resend.Emails.SendParams] = [
59+
{
60+
"from": "onboarding@resend.dev",
61+
"to": ["delivered@resend.dev"],
62+
"subject": "Valid email",
63+
"html": "<strong>This should work!</strong>",
64+
},
65+
{
66+
"from": "onboarding@resend.dev",
67+
"to": [], # Invalid - empty to field
68+
"subject": "Invalid email",
69+
"html": "<strong>This should fail!</strong>",
70+
},
71+
]
72+
73+
options_permissive: resend.Batch.SendOptions = {
74+
"batch_validation": "permissive",
75+
}
76+
77+
result: resend.Batch.SendResponse = resend.Batch.send(
78+
mixed_params, options=options_permissive
79+
)
80+
81+
print(f"Successfully sent {len(result['data'])} emails:")
82+
for email in result["data"]:
83+
print(f" Email id: {email['id']}")
84+
85+
if "errors" in result and result["errors"]:
86+
print(f"Validation errors for {len(result['errors'])} emails:")
87+
for error in result["errors"]:
88+
print(f" Index {error['index']}: {error['message']}")
89+
90+
except resend.exceptions.ResendError as err:
91+
print("Failed to send batch emails")
92+
print(f"Error: {err}")
93+
exit(1)

examples/broadcasts.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import os
2-
from typing import List
32

43
import resend
5-
import resend.broadcasts
64

75
if not os.environ["RESEND_API_KEY"]:
86
raise EnvironmentError("RESEND_API_KEY is missing")
@@ -21,7 +19,7 @@
2119
}
2220

2321
broadcast: resend.Broadcasts.CreateResponse = resend.Broadcasts.create(create_params)
24-
print("Created broadcast !")
22+
print("Created broadcast with ID: {}".format(broadcast["id"]))
2523
print(broadcast)
2624

2725
update_params: resend.Broadcasts.UpdateParams = {
@@ -60,4 +58,19 @@
6058

6159
list_response: resend.Broadcasts.ListResponse = resend.Broadcasts.list()
6260
print("List of broadcasts !\n")
63-
print(list_response)
61+
print(f"Found {len(list_response['data'])} broadcasts")
62+
print(f"Has more broadcasts: {list_response['has_more']}")
63+
64+
print("\n--- Using pagination parameters ---")
65+
if list_response["data"]:
66+
paginated_params: resend.Broadcasts.ListParams = {
67+
"limit": 3,
68+
"after": list_response["data"][0]["id"],
69+
}
70+
paginated_broadcasts: resend.Broadcasts.ListResponse = resend.Broadcasts.list(
71+
params=paginated_params
72+
)
73+
print(f"Retrieved {len(paginated_broadcasts['data'])} broadcasts with pagination")
74+
print(f"Has more broadcasts: {paginated_broadcasts['has_more']}")
75+
else:
76+
print("No broadcasts available for pagination example")

examples/contact_properties.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import os
2+
3+
import resend
4+
5+
if not os.environ["RESEND_API_KEY"]:
6+
raise EnvironmentError("RESEND_API_KEY is missing")
7+
8+
# Create a contact property
9+
create_params: resend.ContactProperties.CreateParams = {
10+
"key": "age",
11+
"type": "number",
12+
"fallback_value": 0,
13+
}
14+
create_response: resend.ContactProperties.CreateResponse = (
15+
resend.ContactProperties.create(create_params)
16+
)
17+
print(f"Created contact property: {create_response}")
18+
19+
# List all contact properties
20+
list_response: resend.ContactProperties.ListResponse = resend.ContactProperties.list()
21+
print(f"Contact properties: {list_response}")
22+
23+
# List with pagination
24+
list_params: resend.ContactProperties.ListParams = {"limit": 10}
25+
paginated_response: resend.ContactProperties.ListResponse = (
26+
resend.ContactProperties.list(list_params)
27+
)
28+
print(f"Limited contact properties: {paginated_response}")
29+
print(f"Has more: {paginated_response.get('has_more', False)}")
30+
31+
# Get a specific contact property
32+
property_id: str = create_response["id"]
33+
property_details: resend.ContactProperty = resend.ContactProperties.get(property_id)
34+
print(f"Contact property details: {property_details}")
35+
36+
# Update a contact property
37+
update_params: resend.ContactProperties.UpdateParams = {
38+
"id": property_id,
39+
"fallback_value": 18,
40+
}
41+
update_response: resend.ContactProperties.UpdateResponse = (
42+
resend.ContactProperties.update(update_params)
43+
)
44+
print(f"Updated contact property: {update_response}")
45+
46+
# Remove a contact property
47+
remove_response: resend.ContactProperties.RemoveResponse = (
48+
resend.ContactProperties.remove(property_id)
49+
)
50+
print(f"Removed contact property: {remove_response}")

0 commit comments

Comments
 (0)