From ffbfdd7bed67af4952612114a1f9c22df6668243 Mon Sep 17 00:00:00 2001 From: David Grayston Date: Mon, 11 Aug 2025 16:27:29 +0100 Subject: [PATCH] feat: Added support for filtering events by event_type in event list operation --- CHANGELOG.md | 6 +++++ .../Resources/Events/Operations/ListEvents.py | 24 ++++++++++++++--- .../Resources/Events/test_EventsClient.py | 26 ++++++++++++++++++- .../Events/Operations/test_ListEvents.py | 13 ++++++++++ 4 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 tests/Unit/Resources/Events/Operations/test_ListEvents.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f18428d..c5b1860c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), Check our main [developer changelog](https://developer.paddle.com/?utm_source=dx&utm_medium=paddle-python-sdk) for information about changes to the Paddle Billing platform, the Paddle API, and other developer tools. +## [Unreleased] + +### Added + +- Added support for filtering events by `event_type` in event list operation, see [related changelog](https://developer.paddle.com/changelog/2025/filter-events-by-type?utm_source=dx&utm_medium=paddle-python-sdk). + ## 1.9.0 - 2025-07-31 ### Added diff --git a/paddle_billing/Resources/Events/Operations/ListEvents.py b/paddle_billing/Resources/Events/Operations/ListEvents.py index a77eaebe..02ba9b43 100644 --- a/paddle_billing/Resources/Events/Operations/ListEvents.py +++ b/paddle_billing/Resources/Events/Operations/ListEvents.py @@ -1,11 +1,29 @@ +from paddle_billing.Entities.Events.EventTypeName import EventTypeName +from paddle_billing.EnumStringify import enum_stringify +from paddle_billing.Exceptions.SdkExceptions.InvalidArgumentException import InvalidArgumentException from paddle_billing.HasParameters import HasParameters - from paddle_billing.Resources.Shared.Operations import Pager class ListEvents(HasParameters): - def __init__(self, pager: Pager | None = None): + def __init__(self, pager: Pager | None = None, event_types: list[EventTypeName] | None = None): self.pager = pager + self.event_types = event_types if event_types is not None else [] + + for field_name, field_value, field_type in [ + ("event_types", self.event_types, EventTypeName), + ]: + invalid_items = [item for item in field_value if not isinstance(item, field_type)] + if invalid_items: + raise InvalidArgumentException.array_contains_invalid_types( + field_name, field_type.__name__, invalid_items + ) def get_parameters(self) -> dict[str, str]: - return self.pager.get_parameters() if self.pager else {} + parameters = {} + if self.pager: + parameters.update(self.pager.get_parameters()) + if self.event_types: + parameters["event_type"] = ",".join(map(enum_stringify, self.event_types)) + + return parameters diff --git a/tests/Functional/Resources/Events/test_EventsClient.py b/tests/Functional/Resources/Events/test_EventsClient.py index f086f3d7..bf95571f 100644 --- a/tests/Functional/Resources/Events/test_EventsClient.py +++ b/tests/Functional/Resources/Events/test_EventsClient.py @@ -3,7 +3,7 @@ from urllib.parse import unquote from paddle_billing.Entities.Collections import EventCollection -from paddle_billing.Entities.Event import Event +from paddle_billing.Entities.Event import Event, EventTypeName from paddle_billing.Resources.Events.Operations import ListEvents from paddle_billing.Resources.Shared.Operations import Pager @@ -37,11 +37,35 @@ class TestEventsClient: ReadsFixtures.read_raw_json_fixture("response/list_default"), "/events?after=evt_01h83xenpcfjyhkqr4x214m02x&order_by=id[asc]&per_page=50", ), + ( + ListEvents( + pager=Pager(after="evt_01h83xenpcfjyhkqr4x214m02x"), + event_types=[EventTypeName.AddressCreated, EventTypeName.TransactionCompleted], + ), + 200, + ReadsFixtures.read_raw_json_fixture("response/list_default"), + "/events?after=evt_01h83xenpcfjyhkqr4x214m02x&order_by=id[asc]&per_page=50&event_type=address.created,transaction.completed", + ), + ( + ListEvents(event_types=[EventTypeName.AddressCreated, EventTypeName.TransactionCompleted]), + 200, + ReadsFixtures.read_raw_json_fixture("response/list_default"), + "/events?event_type=address.created,transaction.completed", + ), + ( + ListEvents(event_types=[EventTypeName.ApiKeyCreated]), + 200, + ReadsFixtures.read_raw_json_fixture("response/list_default"), + "/events?event_type=api_key.created", + ), ], ids=[ "List events", "List paginated events", "List paginated events after specified event id", + "List paginated events with event type filter", + "List events with event type filter", + "List events with single event type filter", ], ) def test_list_events_returns_expected_response( diff --git a/tests/Unit/Resources/Events/Operations/test_ListEvents.py b/tests/Unit/Resources/Events/Operations/test_ListEvents.py new file mode 100644 index 00000000..7f318e38 --- /dev/null +++ b/tests/Unit/Resources/Events/Operations/test_ListEvents.py @@ -0,0 +1,13 @@ +from pytest import raises + +from build.lib.paddle_billing.Resources.Events.Operations import ListEvents + +from paddle_billing.Exceptions.SdkExceptions.InvalidArgumentException import InvalidArgumentException + + +class TestListEvents: + def test_raises_invalid_argument_exception_for_invalid_event_types(self): + with raises(InvalidArgumentException) as exception_info: + ListEvents(event_types=["invalid.event"]) + + assert str(exception_info.value) == "Expected 'event_types' to only contain type 'EventTypeName' ('str' given)"