Browse Source
Ideally I should go back now and implement Paginator for other classes, but for now this is fine.pull/11/merge
5 changed files with 84 additions and 8 deletions
@ -0,0 +1,43 @@ |
|||||
|
import operator |
||||
|
|
||||
|
|
||||
|
class Paginator(object): |
||||
|
""" |
||||
|
Implements a class which provides paginated iteration over an endpoint. |
||||
|
""" |
||||
|
def __init__(self, func, *args, **kwargs): |
||||
|
self.func = func |
||||
|
self.args = args |
||||
|
self.kwargs = kwargs |
||||
|
|
||||
|
self._key = kwargs.pop('key', operator.attrgetter('id')) |
||||
|
self._bulk = kwargs.pop('bulk', False) |
||||
|
self._after = kwargs.pop('after', None) |
||||
|
self._buffer = [] |
||||
|
|
||||
|
def fill(self): |
||||
|
self.kwargs['after'] = self._after |
||||
|
result = self.func(*self.args, **self.kwargs) |
||||
|
|
||||
|
if not len(result): |
||||
|
raise StopIteration |
||||
|
|
||||
|
self._buffer.extend(result) |
||||
|
self._after = self._key(result[-1]) |
||||
|
|
||||
|
def next(self): |
||||
|
return self.__next__() |
||||
|
|
||||
|
def __iter__(self): |
||||
|
return self |
||||
|
|
||||
|
def __next__(self): |
||||
|
if not len(self._buffer): |
||||
|
self.fill() |
||||
|
|
||||
|
if self._bulk: |
||||
|
res = self._buffer |
||||
|
self._buffer = [] |
||||
|
return res |
||||
|
else: |
||||
|
return self._buffer.pop() |
Loading…
Reference in new issue