From 51de4f4f1a6825eac04e51cfdd59fbac1ced5b4e Mon Sep 17 00:00:00 2001 From: Cecilia Stevens <63068179+ceciliastevens@users.noreply.github.com> Date: Tue, 29 Sep 2026 09:50:50 -0400 Subject: [PATCH 1/2] INTEG-3268 - fix bug in trusted_activities iter_all --- CHANGELOG.md | 5 +-- src/_incydr_sdk/__version__.py | 2 +- src/_incydr_sdk/trusted_activities/client.py | 11 ++++-- tests/test_trusted_activities.py | 38 +++++++++++++++++++- 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45a7bd7..a58e468 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,9 +9,10 @@ how a consumer would use the library or CLI tool (e.g. adding unit tests, updating documentation, etc) are not captured here. -## Unreleased +## 2.12.4 - 2026-09-29 +- Fixed an issue where listing trusted activities in some cases would loop infinitely. -### 2.12.3 - 2026-09-11 +## 2.12.3 - 2026-09-11 - The `retry_on_rate_limit` setting, which controls whether the SDK will retry 429 responses. Defaults to on, retrying most 429 responses up to 3 times. Set this to False on SDK initialization if you wish to manually handle retrying 429 responses. When enabled, if retries are exhausted, requests.exceptions.RetryError will be raised. ## 2.12.2 - 2026-06-22 diff --git a/src/_incydr_sdk/__version__.py b/src/_incydr_sdk/__version__.py index 674accb..30a174e 100644 --- a/src/_incydr_sdk/__version__.py +++ b/src/_incydr_sdk/__version__.py @@ -1,4 +1,4 @@ # SPDX-FileCopyrightText: 2022-present Code42 Software # # SPDX-License-Identifier: MIT -__version__ = "2.12.3" +__version__ = "2.12.4" diff --git a/src/_incydr_sdk/trusted_activities/client.py b/src/_incydr_sdk/trusted_activities/client.py index e56b35c..c74ba8b 100644 --- a/src/_incydr_sdk/trusted_activities/client.py +++ b/src/_incydr_sdk/trusted_activities/client.py @@ -104,6 +104,7 @@ def iter_all( """ page_size = page_size or self._parent.settings.page_size + last_page_ids = set() for page_num in count(1): page = self.get_page( page_num=page_num, @@ -112,8 +113,14 @@ def iter_all( sort_key=sort_key, sort_direction=sort_direction, ) - yield from page.trusted_activities - if len(page.trusted_activities) < page_size: + results_to_yield = [ + x for x in page.trusted_activities if x.activity_id not in last_page_ids + ] + yield from results_to_yield + last_page_ids = {x.activity_id for x in page.trusted_activities} + if (len(page.trusted_activities) < page_size) or ( + len(results_to_yield) < page_size + ): break def add_domain( diff --git a/tests/test_trusted_activities.py b/tests/test_trusted_activities.py index 53d803f..d413b80 100644 --- a/tests/test_trusted_activities.py +++ b/tests/test_trusted_activities.py @@ -43,7 +43,7 @@ ], } ], - "activityId": "1324", + "activityId": "13245", "isHighValueSource": True, "description": "This is a description", "principalType": "API_KEY", @@ -142,6 +142,42 @@ def test_iter_all_when_default_params_returns_expected_data( assert total_trusted_activities == 2 +def test_iter_all_when_page_repeats_returns_expected_data( + httpserver_auth: HTTPServer, +): + query_1 = { + "page_num": 1, + "page_size": 2, + } + query_2 = {"page_num": 2, "page_size": 2} + + trusted_activities_data_1 = { + "trustedActivities": [TEST_TRUSTED_ACTIVITY_1, TEST_TRUSTED_ACTIVITY_2], + "totalCount": 2, + } + + httpserver_auth.expect_request( + "/v2/trusted-activities", method="GET", query_string=urlencode(query_1) + ).respond_with_json(trusted_activities_data_1) + + httpserver_auth.expect_request( + "/v2/trusted-activities", method="GET", query_string=urlencode(query_2) + ).respond_with_json(trusted_activities_data_1) + + client = Client() + iterator = client.trusted_activities.v2.iter_all(page_size=2) + total_trusted_activities = 0 + expected_trusted_activities = [TEST_TRUSTED_ACTIVITY_1, TEST_TRUSTED_ACTIVITY_2] + + for item in iterator: + total_trusted_activities += 1 + assert isinstance(item, TrustedActivity) + assert item.json() == json.dumps( + expected_trusted_activities.pop(0), separators=(",", ":") + ) + assert total_trusted_activities == 2 + + def test_add_domain_when_default_params_returns_expected_data( httpserver_auth: HTTPServer, ): From eb123d270d70c5743207405622868c404ed268d7 Mon Sep 17 00:00:00 2001 From: Cecilia Stevens <63068179+ceciliastevens@users.noreply.github.com> Date: Wed, 30 Sep 2026 09:51:28 -0400 Subject: [PATCH 2/2] version release date bump --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a58e468..9cb5592 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ how a consumer would use the library or CLI tool (e.g. adding unit tests, updating documentation, etc) are not captured here. -## 2.12.4 - 2026-09-29 +## 2.12.4 - 2026-09-30 - Fixed an issue where listing trusted activities in some cases would loop infinitely. ## 2.12.3 - 2026-09-11