mirror of
https://github.com/khornberg/octokit.py
synced 2026-05-24 10:06:06 +03:00
Feature: Add pagination
This commit is contained in:
@@ -10,6 +10,8 @@ from jose import jwt
|
||||
from octokit import errors
|
||||
from octokit import utils
|
||||
|
||||
page_regex = re.compile(r'[\?\&]page=(\d+)[_&=\w\d]*>; rel="(\w+)"')
|
||||
|
||||
|
||||
class Base(object):
|
||||
|
||||
@@ -203,3 +205,26 @@ class Octokit(Base):
|
||||
return list((self._convert_to_object(value) for index, value in enumerate(item)))
|
||||
else:
|
||||
return item
|
||||
|
||||
def set_pages(self, obj, previous_page_requested=None):
|
||||
response_headers = obj._response.headers
|
||||
links = response_headers.get('Link', None)
|
||||
if links:
|
||||
matches = re.findall(page_regex, links)
|
||||
if matches:
|
||||
for page, kind in matches:
|
||||
setattr(obj, '{}_page'.format(kind), int(page))
|
||||
setattr(obj, 'pages', getattr(obj, 'last_page', previous_page_requested))
|
||||
setattr(obj, 'has_pages', True)
|
||||
setattr(obj, 'current_page', previous_page_requested or getattr(obj, 'next_page') - 1)
|
||||
setattr(obj, 'is_last_page', obj.pages == obj.current_page)
|
||||
else:
|
||||
setattr(obj, 'has_pages', False)
|
||||
return obj
|
||||
|
||||
def paginate(self, obj, page=1, **kwargs):
|
||||
response = self.set_pages(obj(page=page, **kwargs))
|
||||
yield response.json
|
||||
while not response.is_last_page:
|
||||
response = self.set_pages(obj(page=response.next_page, **kwargs), response.next_page)
|
||||
yield response.json
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
class MockHeaders(object):
|
||||
|
||||
def __init__(self, requested_page):
|
||||
Link = 'Links <https://api.github.com/installation/repositories?page={}>; rel="next", <https://api.github.com/installation/repositories?page=4>; rel="last"'.format(min(requested_page + 1, 4)) # noqa E501
|
||||
self.headers = {'Link': Link}
|
||||
|
||||
|
||||
class MockObject(object):
|
||||
|
||||
def __init__(self, page, kwargs):
|
||||
self._response = MockHeaders(page)
|
||||
self.json = {'page': page, 'kwargs': kwargs}
|
||||
# self.is_last_page = True if page == 4 else False
|
||||
# self.next_page = min(page + 1, 4) if page else 2
|
||||
|
||||
|
||||
def MockResponse(page=None, **kwargs):
|
||||
print('mr', page, kwargs)
|
||||
return MockObject(page, kwargs)
|
||||
|
||||
|
||||
class TestOctokit(object):
|
||||
|
||||
def test_can_instantiate_class(self):
|
||||
@@ -15,3 +36,12 @@ class TestOctokit(object):
|
||||
def test_clients_are_lower_case(self):
|
||||
from octokit import Octokit
|
||||
assert all(client.islower() for client in Octokit.__dict__)
|
||||
|
||||
def test_pagination(self):
|
||||
from octokit import Octokit
|
||||
sut_obj = MockResponse
|
||||
p = Octokit().paginate(sut_obj, param='value')
|
||||
assert next(p) == {'page': 1, 'kwargs': {'param': 'value'}}
|
||||
assert next(p) == {'page': 2, 'kwargs': {'param': 'value'}}
|
||||
assert next(p) == {'page': 3, 'kwargs': {'param': 'value'}}
|
||||
assert next(p) == {'page': 4, 'kwargs': {'param': 'value'}}
|
||||
|
||||
Reference in New Issue
Block a user