diff --git a/credentials/apps/badges/credly/api_client.py b/credentials/apps/badges/credly/api_client.py index 3b587045d..b6584d579 100644 --- a/credentials/apps/badges/credly/api_client.py +++ b/credentials/apps/badges/credly/api_client.py @@ -1,5 +1,6 @@ import base64 import logging +import time from functools import lru_cache from urllib.parse import urljoin @@ -86,7 +87,40 @@ def fetch_badge_templates(self): """ Fetches the badge templates from the Credly API. """ - return self.perform_request("get", f"badge_templates/?filter=state::{CredlyBadgeTemplate.STATES.active}") + results = [] + url = f"badge_templates/?filter=state::{CredlyBadgeTemplate.STATES.active}" + response = self.perform_request("get", url) + results.extend(response.get("data", [])) + + metadata = response.get("metadata", {}) + total_pages = metadata.get("total_pages", 1) + next_page_url = metadata.get("next_page_url") + + # Loop through all remaining pages based on the total_pages value. + # For each iteration, fetch data using the 'next_page_url' provided by the API, + # append the results to the main list, and update the URL for the next request. + # The loop stops when there are no more pages to retrieve. + for _ in range(2, total_pages + 1): + if not next_page_url: + break + + time.sleep(0.2) + + for attempt in range(3): + try: + response = self.perform_request("get", next_page_url) + break + except (requests.Timeout, requests.ConnectionError) as exc: + sleep_time = 0.5 * (2**attempt) + time.sleep(sleep_time) + + if attempt == 2: + raise CredlyError(f"Failed to fetch page due to network error: {exc}") + + results.extend(response.get("data", [])) + next_page_url = response.get("metadata", {}).get("next_page_url") + + return {"data": results} def fetch_event_information(self, event_id): """ diff --git a/credentials/apps/badges/tests/test_api_client.py b/credentials/apps/badges/tests/test_api_client.py index 72b544b32..50c173f92 100644 --- a/credentials/apps/badges/tests/test_api_client.py +++ b/credentials/apps/badges/tests/test_api_client.py @@ -71,10 +71,13 @@ def test_fetch_organization(self): def test_fetch_badge_templates(self): with mock.patch.object(CredlyAPIClient, "perform_request") as mock_perform_request: - mock_perform_request.return_value = {"badge_templates": ["template1", "template2"]} + mock_perform_request.return_value = { + "data": ["template1", "template2"], + "metadata": {"total_pages": 1}, + } result = self.api_client.fetch_badge_templates() mock_perform_request.assert_called_once_with("get", "badge_templates/?filter=state::active") - self.assertEqual(result, {"badge_templates": ["template1", "template2"]}) + self.assertEqual(result, {"data": ["template1", "template2"]}) def test_fetch_event_information(self): event_id = "event123"