-
Notifications
You must be signed in to change notification settings - Fork 457
Description
Describe the bug
I was working with the auto_paging_iter
to implement Relay pagination over invoices, and I encountered an interesting quirk in the way it is implemented. The auto_paging_iter
code currently checks if ending_before
is in the retrieve params and starting_after
is not to decide to reverse the results and paginate backwards:
def _auto_paging_iter(self) -> Iterator[T]:
page = self
while True:
if (
"ending_before" in self._retrieve_params
and "starting_after" not in self._retrieve_params
):
for item in reversed(page):
yield item
page = page.previous_page()
else:
for item in page:
yield item
page = page.next_page()
if page.is_empty:
break
In my code I am passing along all input args because, at least in the services model, the SDK correctly ignores and drops any params
passed as None
:
for stripe_invoice in stripe_client.v1.invoices.list(
params={
"limit": 100,
"customer": dynamodb_alarm_user.customer_id,
"starting_after": parsed_input.after,
"ending_before": parsed_input.before,
"expand": ("data.customer",),
},
options=merge_default_options(
{"stripe_account": dynamodb_jurisdiction.account_id}
),
).auto_paging_iter():
This leads to the following params being shown in the request logs on Stripe's side:
{
"customer": "cus_SyBoRWyoh9GtxR",
"ending_before": "in_1S2FQhBARyXc9bEw3n0eQQwj",
"expand": {
"0": "data.customer"
},
"limit": "100"
}
However, because starting_after
is present in self._retrieve_params
even though it is None
, the auto_paging_iter
logic falls into the else cases and does not reverse the results and calls page.next_page()
instead of page.previous_page()
.
This leads to an incorrect pagination after the first page of results, because it uses the wrong cursors and arguments to retrieve the next page.
To Reproduce
- create N invoices to be able to paginate over under the same stripe account.
- use
stripe_client.v1.invoices.list(params={"limit": 1, "starting_after": None, "ending_before": invoices[-1].id}).auto_paging_iter()
to try and iterate the results.
Expected behavior
The auto paging iter should iterate backwards over the invoices list from the end to the beginning, excluding the invoice specified as ending_before
.
Code snippets
OS
Ubuntu 22.04.5 LTS
Language version
Python 3.13.3
Library version
12.5.0
API version
2025-08-27.basil
Additional context
No response