mirror of
https://github.com/khornberg/octokit.py
synced 2026-05-18 20:09:06 +03:00
Merge pull request #31 from khornberg/feature/routes-and-pagination
Version: 0.8.0
This commit is contained in:
+1
-1
@@ -103,7 +103,7 @@ For merging, you should:
|
||||
|
||||
1. Include passing tests (run ``tox``) [1]_.
|
||||
2. Update documentation when there's new API, functionality etc.
|
||||
4. Add yourself to ``AUTHORS.rst``.
|
||||
3. Add yourself to ``AUTHORS.rst``.
|
||||
|
||||
.. [1] If you don't have all the necessary python versions available locally you can rely on Travis - it will
|
||||
`run the tests <https://travis-ci.org/khornberg/octokit.py/pull_requests>`_ for each change you add in the pull request.
|
||||
|
||||
+1
-5
@@ -8,7 +8,7 @@ Overview
|
||||
:stub-columns: 1
|
||||
|
||||
* - tests
|
||||
- | |travis| |pyup|
|
||||
- | |travis|
|
||||
| |codeclimate| |codeclimate-tests|
|
||||
* - package
|
||||
- | |version| |wheel|
|
||||
@@ -24,10 +24,6 @@ Overview
|
||||
:alt: Travis-CI Build Status
|
||||
:target: https://travis-ci.org/khornberg/octokit.py
|
||||
|
||||
.. |pyup| image:: https://pyup.io/repos/github/khornberg/octokit.py/shield.svg
|
||||
:target: https://pyup.io/repos/github/khornberg/octokit.py/
|
||||
:alt: Updates
|
||||
|
||||
.. |codeclimate| image:: https://codeclimate.com/github/khornberg/octokit.py/badges/gpa.svg
|
||||
:target: https://codeclimate.com/github/khornberg/octokit.py
|
||||
:alt: CodeClimate Quality Status
|
||||
|
||||
@@ -21,7 +21,7 @@ def read(*names, **kwargs):
|
||||
|
||||
setup(
|
||||
name='octokitpy',
|
||||
version='0.7.2',
|
||||
version='0.8.0',
|
||||
license='MIT license',
|
||||
description='Python client for GitHub API',
|
||||
long_description='%s\n%s' % (
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1854,6 +1854,15 @@
|
||||
"accept": "application/vnd.github.machine-man-preview"
|
||||
},
|
||||
"params": {
|
||||
"page": {
|
||||
"type": "number",
|
||||
"description": "Page number of the results to fetch."
|
||||
},
|
||||
"per_page": {
|
||||
"type": "number",
|
||||
"default": "30",
|
||||
"description": "A custom page size up to 100. Default is 30."
|
||||
},
|
||||
"user_id": {
|
||||
"type": "string",
|
||||
"description":
|
||||
|
||||
@@ -1,3 +1,26 @@
|
||||
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( # noqa E501
|
||||
min(requested_page + 1, 4)
|
||||
)
|
||||
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 +38,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