diff --git a/ogr/abstract/git_service.py b/ogr/abstract/git_service.py index ed08e585..caecd7e2 100644 --- a/ogr/abstract/git_service.py +++ b/ogr/abstract/git_service.py @@ -142,9 +142,18 @@ def get_group(self, group_name: str): """ raise NotImplementedError - def get_rate_limit_remaining(self) -> Optional[int]: + def get_rate_limit_remaining( + self, + namespace: Optional[str] = None, + repo: Optional[str] = None, + ) -> Optional[int]: """ - Get the remaining rate limit. + Get the remaining rate limit. If namespace and repo are set, + returns repository-specific rate limit. + + Args: + namespace: Namespace of the project. + repo: Repository name. Returns: Number of remaining API requests, or None if rate limit information diff --git a/ogr/services/forgejo/service.py b/ogr/services/forgejo/service.py index ea1dc590..8994d0b2 100644 --- a/ogr/services/forgejo/service.py +++ b/ogr/services/forgejo/service.py @@ -88,7 +88,11 @@ def get_project_from_url(self, url: str) -> "ForgejoProject": return self.get_project(repo=repo, namespace=namespace) - def get_rate_limit_remaining(self) -> Optional[int]: + def get_rate_limit_remaining( + self, + namespace: Optional[str] = None, + repo: Optional[str] = None, + ) -> Optional[int]: """ There is no way to check rate limit status from Forgejo API. """ diff --git a/ogr/services/github/service.py b/ogr/services/github/service.py index 64215ed1..a0ceb1c0 100644 --- a/ogr/services/github/service.py +++ b/ogr/services/github/service.py @@ -19,7 +19,7 @@ from urllib3.util import Retry from ogr.abstract import AuthMethod, GitUser -from ogr.exceptions import GithubAPIException +from ogr.exceptions import GithubAPIException, OgrException from ogr.factory import use_for_service from ogr.services.base import BaseGitService, GitProject from ogr.services.github.auth_providers import ( @@ -240,8 +240,7 @@ def list_projects( return projects - def get_rate_limit_remaining(self) -> Optional[int]: - rate_limit = self.github.get_rate_limit() + def _get_rate_limit_value(self, rate_limit) -> int: # Handle both old and new PyGithub API versions # Old API in f42 and f43: rate_limit.resources.core.remaining # New API in rawhide (f44): rate_limit.core.remaining (or rate_limit.remaining) @@ -250,4 +249,36 @@ def get_rate_limit_remaining(self) -> Optional[int]: return rate_limit.resources.core.remaining except AttributeError: return rate_limit.core.remaining - return None + + def get_rate_limit_remaining( + self, + namespace: Optional[str] = None, + repo: Optional[str] = None, + ) -> Optional[int]: + # If namespace and repo are provided, use repository-specific instance + # (needed for GithubApp/Tokman auth where service.github is None) + if namespace and repo: + try: + github_instance = self.get_pygithub_instance(namespace, repo) + rate_limit = github_instance.get_rate_limit() + return self._get_rate_limit_value(rate_limit) + except (OgrException, github.GithubException) as ex: + logger.error( + f"Failed to get rate limit from repository-specific instance " + f"for {namespace}/{repo}: {ex}", + ) + return None + + # Try using generic github instance + if not self.github: + auth_type = ( + type(self.authentication).__name__ if self.authentication else "unknown" + ) + raise GithubAPIException( + f"Github instance is not available for rate limit check. " + f"This typically occurs when using {auth_type} authentication, " + f"which requires repository-specific instances.", + ) + + rate_limit = self.github.get_rate_limit() + return self._get_rate_limit_value(rate_limit) diff --git a/ogr/services/gitlab/service.py b/ogr/services/gitlab/service.py index 1824285f..535496f4 100644 --- a/ogr/services/gitlab/service.py +++ b/ogr/services/gitlab/service.py @@ -173,7 +173,11 @@ def list_projects( for project in projects_to_convert ] - def get_rate_limit_remaining(self) -> Optional[int]: + def get_rate_limit_remaining( + self, + namespace: Optional[str] = None, + repo: Optional[str] = None, + ) -> Optional[int]: # python-gitlab doesn't have get_rate_limit(), so we make a lightweight # HEAD request to get rate limit headers from GitLab API # GitLab returns rate limit in headers: ratelimit-remaining @@ -191,10 +195,10 @@ def get_rate_limit_remaining(self) -> Optional[int]: ) return 0 logger.error( - f"Could not get rate limit from GitLab: {e}", + f"Could not get rate limit from GitLab instance {self.gitlab_instance.url}: {e}", ) except Exception as e: logger.error( - f"Could not get rate limit from GitLab: {e}", + f"Could not get rate limit from GitLab instance {self.gitlab_instance.url}: {e}", ) return None diff --git a/ogr/services/pagure/service.py b/ogr/services/pagure/service.py index 9f201c76..354a6ac2 100644 --- a/ogr/services/pagure/service.py +++ b/ogr/services/pagure/service.py @@ -404,7 +404,11 @@ def get_group(self, group_name: str) -> PagureGroup: url = self.get_api_url("group", group_name) return PagureGroup(group_name, self.call_api(url)) - def get_rate_limit_remaining(self) -> Optional[int]: + def get_rate_limit_remaining( + self, + namespace: Optional[str] = None, + repo: Optional[str] = None, + ) -> Optional[int]: """ There is no way to check rate limit status from Pagure API. """