Skip to content

Commit 5b7e110

Browse files
authored
Merge pull request #12 from soda480/0.0.9
Fix paging
2 parents 45936d4 + 66b08dd commit 5b7e110

4 files changed

Lines changed: 19 additions & 32 deletions

File tree

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,9 @@ for repo in client.get('/user/repos', _get='all', _attributes=['full_name']):
6666

6767
`GET page` directive - Yield a page from endpoint
6868
```python
69-
for repo in client.get('/user/repos', _get='page'):
70-
print(repo['full_name'])
69+
for page in client.get('/user/repos', _get='page'):
70+
for repo in page:
71+
print(repo['full_name'])
7172
```
7273

7374
### Projects using `github3api` ###

build.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
authors = [Author('Emilio Reyes', 'emilio.reyes@intel.com')]
3131
summary = 'An advanced REST client for the GitHub API'
3232
url = 'https://github.com/soda480/github3api'
33-
version = '0.0.8'
33+
version = '0.0.9'
3434
default_task = [
3535
'clean',
3636
'analyze',

src/main/python/github3api/githubapi.py

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,37 +55,33 @@ def get_headers(self, **kwargs):
5555
headers['Accept'] = f'application/vnd.github.{self.version}+json'
5656
return headers
5757

58-
def _get_next_endpoint(self, link_header):
59-
""" return next endpoint from link header
58+
def _get_next_endpoint(self, url):
59+
""" return next endpoint
6060
"""
61-
if not link_header:
61+
if not url:
6262
logger.debug('link header is empty')
6363
return
64-
regex = fr".*<https://{self.hostname}(?P<endpoint>/.*?)>; rel=\"next\".*"
65-
match = re.match(regex, link_header)
66-
if match:
67-
endpoint = match.group('endpoint')
68-
logger.debug(f'found next endpoint in link header: {endpoint}')
69-
return endpoint
70-
logger.debug('next endpoints not found in link header')
64+
endpoint = url.replace(f'https://{self.hostname}', '')
65+
logger.debug(f'next endpoint is: {endpoint}')
66+
return endpoint
7167

7268
def _get_all(self, endpoint, **kwargs):
7369
""" return all pages from endpoint
7470
"""
7571
logger.debug(f'get items from: {endpoint}')
7672
items = []
7773
while True:
78-
link_header = None
74+
url = None
7975
response = super(GitHubAPI, self).get(endpoint, raw_response=True, **kwargs)
8076
if response:
8177
data = response.json()
8278
if isinstance(data, list):
8379
items.extend(response.json())
8480
else:
8581
items.append(data)
86-
link_header = response.headers.get('Link')
82+
url = response.links.get('next', {}).get('url')
8783

88-
endpoint = self._get_next_endpoint(link_header)
84+
endpoint = self._get_next_endpoint(url)
8985
if not endpoint:
9086
logger.debug('no more pages to retrieve')
9187
break
@@ -97,9 +93,8 @@ def _get_page(self, endpoint, **kwargs):
9793
"""
9894
while True:
9995
response = super(GitHubAPI, self).get(endpoint, raw_response=True, **kwargs)
100-
for page in response.json():
101-
yield page
102-
endpoint = self._get_next_endpoint(response.headers.get('Link'))
96+
yield response.json()
97+
endpoint = self._get_next_endpoint(response.links.get('next', {}).get('url'))
10398
if not endpoint:
10499
logger.debug('no more pages')
105100
break

src/unittest/python/test_githubapi.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -176,17 +176,11 @@ def test__get_next_endpoint_Should_ReturnNone_When_NoLinkHeader(self, *patches):
176176

177177
def test__get_next_endpoint_Should_ReturnExpected_When_CalledWithNextEndpoint(self, *patches):
178178
client = GitHubAPI(bearer_token='bearer-token')
179-
link_header = '<https://api.github.com/organizations/27781926/repos?page=2>; rel="prev", <https://api.github.com/organizations/27781926/repos?page=4>; rel="next", <https://api.github.com/organizations/27781926/repos?page=4>; rel="last", <https://api.github.com/organizations/27781926/repos?page=1>; rel="first"'
179+
link_header = 'https://api.github.com/organizations/27781926/repos?page=4'
180180
result = client._get_next_endpoint(link_header)
181181
expected_result = '/organizations/27781926/repos?page=4'
182182
self.assertEqual(result, expected_result)
183183

184-
def test__get_next_endpoint_Should_ReturnNone_When_NoNextEndpoint(self, *patches):
185-
client = GitHubAPI(bearer_token='bearer-token')
186-
link_header = '<https://api.github.com/organizations/27781926/repos?page=3>; rel="prev", <https://api.github.com/organizations/27781926/repos?page=1>; rel="first"'
187-
result = client._get_next_endpoint(link_header)
188-
self.assertIsNone(result)
189-
190184
@patch('github3api.GitHubAPI._get_next_endpoint')
191185
@patch('github3api.githubapi.RESTclient.get')
192186
def test__get_all_Should_ReturnExpected_When_GetReturnsList(self, get_patch, get_next_endpoint_patch, *patches):
@@ -264,10 +258,8 @@ def test__get_page_Should_ReturnExpected_When_Called(self, get_patch, get_next_e
264258
]
265259
client = GitHubAPI(bearer_token='bearer-token')
266260
result = client._get_page('endpoint')
267-
self.assertEqual(next(result), 'page1')
268-
self.assertEqual(next(result), 'page2')
269-
self.assertEqual(next(result), 'page3')
270-
self.assertEqual(next(result), 'page4')
261+
self.assertEqual(next(result), ['page1', 'page2'])
262+
self.assertEqual(next(result), ['page3', 'page4'])
271263
with self.assertRaises(StopIteration):
272264
next(result)
273265

@@ -287,8 +279,7 @@ def test__get_page_Should_ReturnExpected_When_NoEndpoint(self, get_patch, get_ne
287279
]
288280
client = GitHubAPI(bearer_token='bearer-token')
289281
result = client._get_page('endpoint')
290-
self.assertEqual(next(result), 'page1')
291-
self.assertEqual(next(result), 'page2')
282+
self.assertEqual(next(result), ['page1', 'page2'])
292283
with self.assertRaises(StopIteration):
293284
next(result)
294285

0 commit comments

Comments
 (0)