Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,22 @@ def get_rows(
) -> Iterator[list[dict[str, Any]]]:
config = TABOOLA_ENDPOINTS[endpoint]
session = _get_session(client_secret)
token = _mint_token(session, client_id, client_secret)

# Unlike the mid-sync re-mint below, nothing else retries this initial mint, so a
# transient token-endpoint failure here needs its own backoff instead of failing the
# sync outright. Don't reuse `fetch`'s retry for this: it also retries on
# TaboolaRetryableError, and re-mint failures already propagate into that retry via the
# 401 branch below, so decorating the mint itself too would let the two retries compound.
@retry(
retry=retry_if_exception_type(TaboolaRetryableError),
stop=stop_after_attempt(MAX_RETRY_ATTEMPTS),
wait=wait_exponential_jitter(initial=2, max=90),
reraise=True,
Comment thread
Gilbert09 marked this conversation as resolved.
)
def mint_initial_token() -> str:
return _mint_token(session, client_id, client_secret)

token = mint_initial_token()
account_base = f"{TABOOLA_API_BASE_URL}/{_encode_path_segment(account_id)}"

@retry(
Expand All @@ -114,7 +129,8 @@ def fetch(url: str) -> dict[str, Any]:
nonlocal token
response = session.get(url, headers={"Authorization": f"Bearer {token}"}, timeout=REQUEST_TIMEOUT_SECONDS)

# Access tokens are short-lived; re-mint once if one expires mid-sync.
# Access tokens are short-lived; re-mint once if one expires mid-sync. A retryable
# failure here isn't retried separately — it propagates to this function's own retry.
if response.status_code == 401:
token = _mint_token(session, client_id, client_secret)
response = session.get(url, headers={"Authorization": f"Bearer {token}"}, timeout=REQUEST_TIMEOUT_SECONDS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,20 @@ def test_mid_sync_401_re_mints_token(self, mock_session):
assert batches == [[{"id": "1"}]]
assert mock_session.return_value.post.call_count == 2

@mock.patch("tenacity.nap.time.sleep", return_value=None)
@mock.patch(f"{_MODULE}.make_tracked_session")
def test_initial_token_mint_retries_on_transient_error(self, mock_session, _sleep):
mock_session.return_value.post.side_effect = [
_response({}, status_code=503),
_token_response(),
]
mock_session.return_value.get.return_value = _response({"results": [{"id": "1"}]})

batches = list(get_rows("cid", "sec", "acct", "campaigns", mock.MagicMock(), _make_manager()))

assert batches == [[{"id": "1"}]]
assert mock_session.return_value.post.call_count == 2


class TestCampaignItemsFanOut:
@mock.patch(f"{_MODULE}.make_tracked_session")
Expand Down
Loading