Skip to content

Commit a76ba97

Browse files
authored
Add: pagination support for issue requests (#140)
1 parent b368421 commit a76ba97

File tree

2 files changed

+49
-6
lines changed

2 files changed

+49
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- Fix: Refactor all issue related GitHub methods to gh_client module (@lwasser, #125)
1313
- Add: support for partners and emeritus_editor in contributor model (@lwasser, #133)
1414
- Fix: Refactor all contributor GitHub related methods into gh_client module from contributors module (@lwasser, #125)
15+
- Fix: Add support for pagination in github issue requests (@lwasser, #139)
1516

1617

1718
## [v0.2.3] - 2024-02-29

src/pyosmeta/github_api.py

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import logging
1313
import os
14+
import time
1415

1516
import requests
1617
from dataclasses import dataclass
@@ -80,28 +81,69 @@ def api_endpoint(self):
8081
)
8182
return url
8283

84+
def handle_rate_limit(self, response):
85+
"""
86+
Handle rate limiting by waiting until the rate limit resets.
87+
88+
Parameters
89+
----------
90+
response : requests.Response
91+
The response object from the API request.
92+
93+
Notes
94+
-----
95+
This method checks the remaining rate limit in the response headers.
96+
If the remaining requests are exhausted, it calculates the time
97+
until the rate limit resets and sleeps accordingly.
98+
"""
99+
100+
if "X-RateLimit-Remaining" in response.headers:
101+
remaining_requests = int(response.headers["X-RateLimit-Remaining"])
102+
if remaining_requests <= 0:
103+
reset_time = int(response.headers["X-RateLimit-Reset"])
104+
sleep_time = max(reset_time - time.time(), 0) + 1
105+
time.sleep(sleep_time)
106+
83107
def return_response(self) -> list[dict[str, object]]:
84108
"""
85109
Make a GET request to the Github API endpoint
86110
Deserialize json response to list of dicts.
87111
112+
Handles pagination as github has a REST api 100 request max.
113+
88114
Returns
89115
-------
90116
list
91117
List of dict items each containing a review issue
92118
"""
93119

120+
results = []
121+
# This is computed as a property. Reassign here to support pagination
122+
# and new urls for each page
123+
api_endpoint_url = self.api_endpoint
94124
try:
95-
response = requests.get(
96-
self.api_endpoint,
97-
headers={"Authorization": f"token {self.get_token()}"},
98-
)
99-
response.raise_for_status()
125+
while True:
126+
response = requests.get(
127+
api_endpoint_url,
128+
headers={"Authorization": f"token {self.get_token()}"},
129+
)
130+
response.raise_for_status()
131+
results.extend(response.json())
132+
133+
# Check if there are more pages to fetch
134+
if "next" in response.links:
135+
next_url = response.links["next"]["url"]
136+
api_endpoint_url = next_url
137+
else:
138+
break
139+
140+
# Handle rate limiting
141+
self.handle_rate_limit(response)
100142

101143
except requests.HTTPError as exception:
102144
raise exception
103145

104-
return response.json()
146+
return results
105147

106148
def get_repo_meta(self, url: str) -> dict[str, Any] | None:
107149
"""

0 commit comments

Comments
 (0)