Skip to content

Commit 6525338

Browse files
authored
Handle case when Github releases rate limit is reached. (#204)
* Handle case when Github releases rate limit is reached. * Attach GITHUB_TOKEN to releases request if available. * Fix test. * Fix test. * Ruff fix.
1 parent 93ab01b commit 6525338

2 files changed

Lines changed: 35 additions & 4 deletions

File tree

comfy_cli/command/install.py

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,17 @@ def execute(
188188
clone_comfyui(url=url, repo_dir=repo_dir)
189189

190190
if version != "nightly":
191-
checkout_stable_comfyui(version=version, repo_dir=repo_dir)
191+
try:
192+
checkout_stable_comfyui(version=version, repo_dir=repo_dir)
193+
except GitHubRateLimitError as e:
194+
rprint(f"[bold red]Error checking out ComfyUI version: {e}[/bold red]")
195+
sys.exit(1)
192196

193197
elif not check_comfy_repo(repo_dir)[0]:
194198
rprint(
195199
f"[bold red]'{repo_dir}' already exists. But it is an invalid ComfyUI repository. Remove it and retry.[/bold red]"
196200
)
197-
exit(-1)
201+
sys.exit(-1)
198202

199203
# checkout specified commit
200204
if commit is not None:
@@ -281,12 +285,39 @@ def validate_version(version: str) -> Optional[str]:
281285
) from exc
282286

283287

288+
class GitHubRateLimitError(Exception):
289+
"""Raised when GitHub API rate limit is exceeded"""
290+
291+
284292
def fetch_github_releases(repo_owner: str, repo_name: str) -> List[Dict[str, str]]:
285293
"""
286294
Fetch the list of releases from the GitHub API.
295+
Handles rate limiting by logging the wait time.
287296
"""
288297
url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/releases"
289-
response = requests.get(url)
298+
299+
headers = {}
300+
if github_token := os.getenv("GITHUB_TOKEN"):
301+
headers["Authorization"] = f"Bearer {github_token}"
302+
303+
response = requests.get(url, headers=headers, timeout=5)
304+
305+
# Handle rate limiting
306+
if response.status_code in (403, 429):
307+
# Check rate limit headers
308+
remaining = int(response.headers.get("x-ratelimit-remaining", 0))
309+
if remaining == 0:
310+
reset_time = int(response.headers.get("x-ratelimit-reset", 0))
311+
message = f"Primary rate limit from Github exceeded! Please retry after: {reset_time})"
312+
raise GitHubRateLimitError(message)
313+
314+
if "retry-after" in response.headers:
315+
wait_seconds = int(response.headers["retry-after"])
316+
message = f"Rate limit from Github exceeded! Please wait {wait_seconds} seconds before retrying."
317+
rprint(f"[yellow]{message}[/yellow]")
318+
raise GitHubRateLimitError(message)
319+
320+
response.raise_for_status()
290321
return response.json()
291322

292323

tests/comfy_cli/test_install.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def test_fetch_releases_success(mock_get):
5353
assert len(releases) == 2
5454
assert releases[0]["tag_name"] == "v1.0.0"
5555
assert releases[1]["tag_name"] == "v1.1.0"
56-
mock_get.assert_called_once_with("https://api.github.com/repos/owner/repo/releases")
56+
mock_get.assert_called_once_with("https://api.github.com/repos/owner/repo/releases", headers={}, timeout=5)
5757

5858

5959
@patch("requests.get")

0 commit comments

Comments
 (0)