From 0d5400142d660e91640d94b2e425d1c851404035 Mon Sep 17 00:00:00 2001 From: dielduarte Date: Tue, 25 Aug 2026 23:33:48 -0300 Subject: [PATCH 1/4] feat: add update/update_async for renaming a segment --- examples/segments.py | 9 +++++ resend/segments/_segments.py | 69 ++++++++++++++++++++++++++++++++++++ tests/segments_test.py | 29 +++++++++++++++ 3 files changed, 107 insertions(+) diff --git a/examples/segments.py b/examples/segments.py index fcc21cd..01a7c4a 100644 --- a/examples/segments.py +++ b/examples/segments.py @@ -19,6 +19,15 @@ print(f"\n✓ Retrieved segment: {seg['name']}") print(f" Created at: {seg['created_at']}") +# Update the segment's name +update_params: resend.Segments.UpdateParams = { + "name": "VIP Newsletter Subscribers (renamed)", +} +updated_segment: resend.Segments.UpdateSegmentResponse = resend.Segments.update( + id=segment["id"], params=update_params +) +print(f"\n✓ Updated segment: {updated_segment['name']}") + # List all segments segments: resend.Segments.ListResponse = resend.Segments.list() print(f"\n✓ List of segments: {[s['name'] for s in segments['data']]}") diff --git a/resend/segments/_segments.py b/resend/segments/_segments.py index 6793798..5cc2589 100644 --- a/resend/segments/_segments.py +++ b/resend/segments/_segments.py @@ -110,6 +110,35 @@ class CreateParams(TypedDict): The name of the segment. """ + class UpdateSegmentResponse(BaseResponse): + """ + UpdateSegmentResponse is the type that wraps the response of the segment that was updated + + Attributes: + object (str): The object type, "segment" + id (str): The ID of the updated segment + name (str): The name of the updated segment + """ + + object: str + """ + The object type, "segment" + """ + id: str + """ + The ID of the updated segment + """ + name: str + """ + The name of the updated segment + """ + + class UpdateParams(TypedDict): + name: str + """ + The new name of the segment. + """ + @classmethod def create(cls, params: CreateParams) -> CreateSegmentResponse: """ @@ -171,6 +200,26 @@ def get(cls, id: str) -> Segment: ).perform_with_content() return resp + @classmethod + def update(cls, id: str, params: UpdateParams) -> UpdateSegmentResponse: + """ + Update an existing segment's name. + see more: https://resend.com/docs/api-reference/segments/update-segment + + Args: + id (str): The segment ID + params (UpdateParams): The segment update parameters + - name: The new name of the segment + + Returns: + UpdateSegmentResponse: The updated segment response + """ + path = f"/segments/{id}" + resp = request.Request[Segments.UpdateSegmentResponse]( + path=path, params=cast(Dict[Any, Any], params), verb="patch" + ).perform_with_content() + return resp + @classmethod def remove(cls, id: str) -> RemoveSegmentResponse: """ @@ -245,6 +294,26 @@ async def get_async(cls, id: str) -> Segment: ).perform_with_content() return resp + @classmethod + async def update_async(cls, id: str, params: UpdateParams) -> UpdateSegmentResponse: + """ + Update an existing segment's name (async). + see more: https://resend.com/docs/api-reference/segments/update-segment + + Args: + id (str): The segment ID + params (UpdateParams): The segment update parameters + - name: The new name of the segment + + Returns: + UpdateSegmentResponse: The updated segment response + """ + path = f"/segments/{id}" + resp = await AsyncRequest[Segments.UpdateSegmentResponse]( + path=path, params=cast(Dict[Any, Any], params), verb="patch" + ).perform_with_content() + return resp + @classmethod async def remove_async(cls, id: str) -> RemoveSegmentResponse: """ diff --git a/tests/segments_test.py b/tests/segments_test.py index 7f3c9fa..4fea28a 100644 --- a/tests/segments_test.py +++ b/tests/segments_test.py @@ -50,6 +50,35 @@ def test_should_get_segments_raise_exception_when_no_content(self) -> None: with self.assertRaises(NoContentError): _ = resend.Segments.get(id="78261eea-8f8b-4381-83c6-79fa7120f1cf") + def test_segments_update(self) -> None: + self.set_mock_json( + { + "object": "segment", + "id": "78261eea-8f8b-4381-83c6-79fa7120f1cf", + "name": "Renamed Segment", + } + ) + + params: resend.Segments.UpdateParams = { + "name": "Renamed Segment", + } + segment = resend.Segments.update( + id="78261eea-8f8b-4381-83c6-79fa7120f1cf", params=params + ) + assert segment["object"] == "segment" + assert segment["id"] == "78261eea-8f8b-4381-83c6-79fa7120f1cf" + assert segment["name"] == "Renamed Segment" + + def test_should_update_segments_raise_exception_when_no_content(self) -> None: + self.set_mock_json(None) + params: resend.Segments.UpdateParams = { + "name": "Renamed Segment", + } + with self.assertRaises(NoContentError): + _ = resend.Segments.update( + id="78261eea-8f8b-4381-83c6-79fa7120f1cf", params=params + ) + def test_segments_remove(self) -> None: self.set_mock_json( { From 7001d32e6889783f754e431a1586ccedd95be8d9 Mon Sep 17 00:00:00 2001 From: dielduarte Date: Tue, 25 Aug 2026 23:42:35 -0300 Subject: [PATCH 2/4] test: add async coverage for Segments.update_async --- tests/segments_async_test.py | 42 ++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/segments_async_test.py diff --git a/tests/segments_async_test.py b/tests/segments_async_test.py new file mode 100644 index 0000000..28f5f55 --- /dev/null +++ b/tests/segments_async_test.py @@ -0,0 +1,42 @@ +import pytest + +import resend +from resend.exceptions import NoContentError +from tests.conftest import AsyncResendBaseTest + +# flake8: noqa + +pytestmark = pytest.mark.asyncio + + +class TestResendSegmentsAsync(AsyncResendBaseTest): + async def test_segments_update_async(self) -> None: + self.set_mock_json( + { + "object": "segment", + "id": "78261eea-8f8b-4381-83c6-79fa7120f1cf", + "name": "Renamed Segment", + } + ) + + params: resend.Segments.UpdateParams = { + "name": "Renamed Segment", + } + segment = await resend.Segments.update_async( + id="78261eea-8f8b-4381-83c6-79fa7120f1cf", params=params + ) + assert segment["object"] == "segment" + assert segment["id"] == "78261eea-8f8b-4381-83c6-79fa7120f1cf" + assert segment["name"] == "Renamed Segment" + + async def test_should_update_segments_async_raise_exception_when_no_content( + self, + ) -> None: + self.set_mock_json(None) + params: resend.Segments.UpdateParams = { + "name": "Renamed Segment", + } + with pytest.raises(NoContentError): + _ = await resend.Segments.update_async( + id="78261eea-8f8b-4381-83c6-79fa7120f1cf", params=params + ) From 9bbdd65141c89fd00197b770fd2399586ba9fca5 Mon Sep 17 00:00:00 2001 From: dielduarte Date: Wed, 26 Aug 2026 09:38:56 -0300 Subject: [PATCH 3/4] fix: update segment response no longer includes name --- examples/segments.py | 2 +- resend/segments/_segments.py | 5 ----- tests/segments_async_test.py | 2 -- tests/segments_test.py | 2 -- 4 files changed, 1 insertion(+), 10 deletions(-) diff --git a/examples/segments.py b/examples/segments.py index 01a7c4a..a799308 100644 --- a/examples/segments.py +++ b/examples/segments.py @@ -26,7 +26,7 @@ updated_segment: resend.Segments.UpdateSegmentResponse = resend.Segments.update( id=segment["id"], params=update_params ) -print(f"\n✓ Updated segment: {updated_segment['name']}") +print(f"\n✓ Updated segment: {updated_segment['id']}") # List all segments segments: resend.Segments.ListResponse = resend.Segments.list() diff --git a/resend/segments/_segments.py b/resend/segments/_segments.py index 5cc2589..a431c50 100644 --- a/resend/segments/_segments.py +++ b/resend/segments/_segments.py @@ -117,7 +117,6 @@ class UpdateSegmentResponse(BaseResponse): Attributes: object (str): The object type, "segment" id (str): The ID of the updated segment - name (str): The name of the updated segment """ object: str @@ -128,10 +127,6 @@ class UpdateSegmentResponse(BaseResponse): """ The ID of the updated segment """ - name: str - """ - The name of the updated segment - """ class UpdateParams(TypedDict): name: str diff --git a/tests/segments_async_test.py b/tests/segments_async_test.py index 28f5f55..abff364 100644 --- a/tests/segments_async_test.py +++ b/tests/segments_async_test.py @@ -15,7 +15,6 @@ async def test_segments_update_async(self) -> None: { "object": "segment", "id": "78261eea-8f8b-4381-83c6-79fa7120f1cf", - "name": "Renamed Segment", } ) @@ -27,7 +26,6 @@ async def test_segments_update_async(self) -> None: ) assert segment["object"] == "segment" assert segment["id"] == "78261eea-8f8b-4381-83c6-79fa7120f1cf" - assert segment["name"] == "Renamed Segment" async def test_should_update_segments_async_raise_exception_when_no_content( self, diff --git a/tests/segments_test.py b/tests/segments_test.py index 4fea28a..6e970f7 100644 --- a/tests/segments_test.py +++ b/tests/segments_test.py @@ -55,7 +55,6 @@ def test_segments_update(self) -> None: { "object": "segment", "id": "78261eea-8f8b-4381-83c6-79fa7120f1cf", - "name": "Renamed Segment", } ) @@ -67,7 +66,6 @@ def test_segments_update(self) -> None: ) assert segment["object"] == "segment" assert segment["id"] == "78261eea-8f8b-4381-83c6-79fa7120f1cf" - assert segment["name"] == "Renamed Segment" def test_should_update_segments_raise_exception_when_no_content(self) -> None: self.set_mock_json(None) From 74119a95a64ef8339a18505c05518bc2f8c13fb9 Mon Sep 17 00:00:00 2001 From: dielduarte Date: Wed, 26 Aug 2026 10:20:22 -0300 Subject: [PATCH 4/4] test: drop 'should' from the update_async test name --- tests/segments_async_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/segments_async_test.py b/tests/segments_async_test.py index abff364..7ec3943 100644 --- a/tests/segments_async_test.py +++ b/tests/segments_async_test.py @@ -27,7 +27,7 @@ async def test_segments_update_async(self) -> None: assert segment["object"] == "segment" assert segment["id"] == "78261eea-8f8b-4381-83c6-79fa7120f1cf" - async def test_should_update_segments_async_raise_exception_when_no_content( + async def test_update_segments_async_raises_exception_when_no_content( self, ) -> None: self.set_mock_json(None)