Pagination
A paginated
decorator is provided to help when the same function should be called
several times, with each call returning a partial set of the data.
Note
This works for any functions and methods, not just for methods of Client
subclasses.
Overview
Your friend Ranis is a well-known wizard who has several spells for sale. She gives you a function that returns the spells she's selling, given a budget. However, at most 3 items are returned at a time, so you have to call it multiple times to retrieve the list of all her spells.
By page index
Given the following list_spells
function:
>>> list_spells(max_price=50, page=0)
['Crushing Burden Touch', 'Great Burden of Sin', 'Heavy Burden']
>>> list_spells(max_price=50, page=1)
['Strong Feather', "Tinur's Hoptoad", "Ulms's Juicedaw's Feather"]
>>> list_spells(max_price=50, page=2)
['Far Silence', 'Soul Trap']
>>> list_spells(max_price=50, page=3)
[]
Use pagination.page
:
>>> from sdkite import paginated
>>> @paginated()
... def get_spells1(pagination, max_price):
... return list_spells(max_price=max_price, page=pagination.page)
>>> result = get_spells1(50) # the only parameter of get_spells1 is max_price
>>> isinstance(result, Iterator)
True
>>> for spell in result:
... print(repr(spell))
'Crushing Burden Touch'
'Great Burden of Sin'
'Heavy Burden'
'Strong Feather'
"Tinur's Hoptoad"
"Ulms's Juicedaw's Feather"
'Far Silence'
'Soul Trap'
By the position of the first item
Given the following list_spells
function:
>>> list_spells(max_price=50, offset=0)
['Crushing Burden Touch', 'Great Burden of Sin', 'Heavy Burden']
>>> list_spells(max_price=50, offset=1) # overlap with last call
['Great Burden of Sin', 'Heavy Burden', 'Strong Feather']
Use pagination.offset
:
>>> @paginated()
... def get_spells2(pagination, max_price):
... return list_spells(max_price=max_price, offset=pagination.offset)
>>> for spell in get_spells2(50):
... print(repr(spell))
'Crushing Burden Touch'
'Great Burden of Sin'
'Heavy Burden'
'Strong Feather'
"Tinur's Hoptoad"
"Ulms's Juicedaw's Feather"
'Far Silence'
'Soul Trap'
By the reference to the next page
To avoid having invalid results due to items changing between two calls, some APIs gives you a reference to the next page of your query.
Given the following list_spells_with_ref
function:
>>> list_spells_with_ref(max_price=50)
(['Crushing Burden Touch', 'Great Burden of Sin', 'Heavy Burden'], '57656c636')
>>> list_spells_with_ref(cursor="57656c636")
(['Strong Feather', "Tinur's Hoptoad", "Ulms's Juicedaw's Feather"], 'f6d652074')
>>> list_spells_with_ref(cursor="f6d652074")
(['Far Silence', 'Soul Trap'], '6f2042616')
>>> list_spells_with_ref(cursor="6f2042616")
([], 'c6d6f7261')
Use pagination.context
to store this reference:
>>> @paginated()
... def get_spells3(pagination, max_price):
... if pagination.context is None:
... data, next_cursor = list_spells_with_ref(max_price=max_price)
... else:
... data, next_cursor = list_spells_with_ref(cursor=pagination.context)
... pagination.context = next_cursor
... return data
>>> for spell in get_spells3(50):
... print(repr(spell))
'Crushing Burden Touch'
'Great Burden of Sin'
'Heavy Burden'
'Strong Feather'
"Tinur's Hoptoad"
"Ulms's Juicedaw's Feather"
'Far Silence'
'Soul Trap'
Usage
Decorated function
The decorated function must take pagination
as its first parameter, which will be
inserted by the decorator with a Pagination
instance.
Note
For methods of a class, the pagination
parameter must come just after self
.
An iterable must be returned by the decorated function. Items of this iterable will be consumed one by one only when needed.
Note
The returned iterable can be of any size, which can vary at each call. However, if
the iterable is empty, it will be assumed that the current page is the last, unless
stop_when_empty=False
was passed to paginated
.
The Pagination
object
The following attributes of pagination
are available:
page
(read-only)-
The index of the current page.
offset
(read-only)-
The index of the next item.
context
-
Any arbitrary data that can be set on the
pagination
variable to persist from one call of the decorated function to the other. finished
(read-only)-
A boolean indicating if a new page is expected to come after the current one.
finish()
-
Call this method to indicate that the current page is the last one.
The paginated
decorator
The following parameters can be passed to paginated
:
page
,offset
,context
-
The initial values of the corresponding attributes of the
Pagination
object passed to the decorated function (default to0
,0
andNone
respectively). stop_when_empty
-
Whether a next page will be fetched if no items have been generated on the current page (defaults to
True
). IfFalse
, thefinish
method of thePagination
object must me called to tell when to stop.