Skip to content

Commit 884897e

Browse files
authored
fix(low-code cdk pagination): Fix the offset strategy so that it resets back to 0 when a stream is an incremental data feed (#202)
1 parent f8cb659 commit 884897e

File tree

5 files changed

+48
-7
lines changed

5 files changed

+48
-7
lines changed

airbyte_cdk/sources/declarative/requesters/paginators/strategies/offset_increment.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ def next_page_token(
8383
return self._offset
8484

8585
def reset(self, reset_value: Optional[Any] = 0) -> None:
86-
if not isinstance(reset_value, int):
86+
if reset_value is None:
87+
self._offset = 0
88+
elif not isinstance(reset_value, int):
8789
raise ValueError(
8890
f"Reset value {reset_value} for OffsetIncrement pagination strategy was not an integer"
8991
)

airbyte_cdk/sources/declarative/requesters/paginators/strategies/stop_condition.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ def next_page_token(
5353
return self._delegate.next_page_token(response, last_page_size, last_record)
5454

5555
def reset(self, reset_value: Optional[Any] = None) -> None:
56-
self._delegate.reset(reset_value)
56+
if reset_value:
57+
self._delegate.reset(reset_value)
58+
else:
59+
self._delegate.reset()
5760

5861
def get_page_size(self) -> Optional[int]:
5962
return self._delegate.get_page_size()

unit_tests/sources/declarative/requesters/paginators/test_default_paginator.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import requests
1010

1111
from airbyte_cdk.sources.declarative.decoders import JsonDecoder, XmlDecoder
12+
from airbyte_cdk.sources.declarative.incremental import DatetimeBasedCursor
1213
from airbyte_cdk.sources.declarative.interpolation.interpolated_boolean import InterpolatedBoolean
1314
from airbyte_cdk.sources.declarative.requesters.paginators.default_paginator import (
1415
DefaultPaginator,
@@ -22,6 +23,10 @@
2223
from airbyte_cdk.sources.declarative.requesters.paginators.strategies.offset_increment import (
2324
OffsetIncrement,
2425
)
26+
from airbyte_cdk.sources.declarative.requesters.paginators.strategies.stop_condition import (
27+
CursorStopCondition,
28+
StopConditionPaginationStrategyDecorator,
29+
)
2530
from airbyte_cdk.sources.declarative.requesters.request_path import RequestPath
2631

2732

@@ -356,6 +361,40 @@ def test_reset(inject_on_first_request):
356361
assert request_parameters_for_second_request != request_parameters_after_reset
357362

358363

364+
def test_data_feed_paginator_with_stop_page_condition():
365+
config = {}
366+
367+
cursor = DatetimeBasedCursor(
368+
cursor_field="updated_at",
369+
datetime_format="%Y-%m-%d",
370+
start_datetime="2024-01-01",
371+
config=config,
372+
parameters={},
373+
)
374+
375+
wrapped_strategy = StopConditionPaginationStrategyDecorator(
376+
_delegate=OffsetIncrement(
377+
config={}, page_size=2, inject_on_first_request=False, parameters={}
378+
),
379+
stop_condition=CursorStopCondition(cursor=cursor),
380+
)
381+
382+
paginator = DefaultPaginator(
383+
pagination_strategy=wrapped_strategy,
384+
config=config,
385+
url_base="https://airbyte.io",
386+
parameters={},
387+
page_size_option=RequestOption(
388+
inject_into=RequestOptionType.request_parameter, field_name="limit", parameters={}
389+
),
390+
page_token_option=RequestOption(
391+
inject_into=RequestOptionType.request_parameter, field_name="offset", parameters={}
392+
),
393+
)
394+
395+
paginator.reset()
396+
397+
359398
def test_initial_token_with_offset_pagination():
360399
page_size_request_option = RequestOption(
361400
inject_into=RequestOptionType.request_parameter, field_name="limit", parameters={}

unit_tests/sources/declarative/requesters/paginators/test_offset_increment.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,5 @@ def test_offset_increment_reset(reset_value, expected_initial_token, expected_er
104104
with pytest.raises(expected_error):
105105
paginator_strategy.reset(reset_value=reset_value)
106106
else:
107-
if reset_value is None:
108-
paginator_strategy.reset()
109-
else:
110-
paginator_strategy.reset(reset_value=reset_value)
107+
paginator_strategy.reset(reset_value=reset_value)
111108
assert paginator_strategy.initial_token == expected_initial_token

unit_tests/sources/declarative/requesters/paginators/test_stop_condition.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def test_when_reset_then_delegate(mocked_pagination_strategy, mocked_stop_condit
108108
mocked_pagination_strategy, mocked_stop_condition
109109
)
110110
decorator.reset()
111-
mocked_pagination_strategy.reset.assert_called_once_with(None)
111+
mocked_pagination_strategy.reset.assert_called_once_with()
112112

113113

114114
def test_when_get_page_size_then_delegate(mocked_pagination_strategy, mocked_stop_condition):

0 commit comments

Comments
 (0)