Ich versuche, die Anzahl der offenen Probleme mit dem folgenden Code in meiner Flask-Anwendung abzurufen.
g = Github()
repo = g.get_repo(repo_name)
open_pulls = repo.get_pulls(state='open')
open_pull_titles = [pull.title for pull in open_pulls]
open_issues = repo.get_issues(state='open')
open_issues = [issue for issue in open_issues if issue.title not in open_pull_titles]
und ich bekomme den Fehler github.GithubException.RateLimitExceededException:
.
repo.get_issues()
gibt die Anzahl der offenen Issues plus Pull-Requests zurück.
Wenn ich das richtig verstehe, ist der Rückgabetyp von get_issues und get_pulls PaginatedList. Es verwendet yield element
für die Iteration. Die Anfrage wird also erst bei open_issues = [issue for issue in open_issues if issue.title not in open_pull_titles]
. Wenn Ihre Tokenlimits erreicht sind, wird die RateLimitExceedException ausgelöst.
Gibt es einen Workaround?
g = Github()
Haben Sie sich bei diesem Schritt authentifiziert? Die öffentliche API hat weniger Ratenbegrenzungen.
g = Github()
Haben Sie sich bei diesem Schritt authentifiziert? Die öffentliche API hat weniger Ratenbegrenzungen.
Ja, ich habe diesen Schritt authentifiziert.
@242jainabhi
Die Dinge, die ich normalerweise tue, wenn ich das Ratenlimit erreiche, ist, das Programm für einige Zeit aufzuhalten.
Anstatt das Listenverständnis zu verwenden, kann ich nur eine gemeinsame Schleife mit try-catch verwenden. Rufen Sie nach dem Abfangen einer Ratenlimitausnahme die Sleep-Funktion auf, um eine Weile zu warten, und überprüfen Sie das Ratenlimit erneut mit der GitHub-API. Der Code wird nur fortgesetzt, wenn die Ratengrenze wieder auf 5000 liegt.
Es tut mir leid, dass ich einen Teil des Codes verpasst habe. Unten ist der Code in Fortsetzung des Codes im ersten Kommentar.
Ich greife auf das created_at
Datum für alle offenen Ausgaben zu. Dies greift wieder auf die API für alle Probleme zu und führt daher am Ende zu mehr Aufrufen als das Limit.
for issue in open_issues:
created_at = issue.created_at.timestamp()
Ich konnte keine Lösung für dieses Problem finden. Selbst wenn ich die Anfragen authentifiziere, wird das Limit ausgeschöpft, wenn es zu viele Probleme gibt (sagen wir 2000).
Etwas wie das:
repositories = g.search_repositories(
query='stars:>=10 fork:true language:python')
Löst auch die Ratenbegrenzung aus. Ich nehme an, es macht die Paginierung automatisch und das löst das Ratenlimit aus? Gibt es eine Möglichkeit, dies manuell zu tun, damit ich pausieren kann?
Mir ist jetzt klar, dass dies ein echtes Problem ist.
Eine mögliche Problemumgehung könnte ein Code-Snippet wie das folgende sein. Ich habe es noch nicht ausprobiert, lass es mich wissen, ob es funktioniert oder nicht.
iter_obj=iter(open_issues) ## PaginatedList is a generator
while True:
try:
issue=next(iter_obj)
## do something
except StopIteration:
break # loop end
except github.GithubException.RateLimitExceededException:
sleep(3600) # sleep 1 hour
## check token limits
continue
@wangpeipei90 Funktioniert nicht.
Aus irgendeinem Grund ist dieses Verhalten höchst unvorhersehbar und nervtötend.
Mein Programm kann die ratelimit-API effektiv zyklisch durchlaufen und präventiv aufrufen, um zu überprüfen, ob sie ein bis zwei Stunden lang innerhalb der Grenzen liegt, bevor zufällig eine 403 ausgegeben wird.
Eine gewisse Einhaltung der nativen Ratenbegrenzung wäre hier herzlich willkommen. Es sollte kein erwartetes Verhalten sein, auf Intuition basierende Sleeps zu implementieren, wenn Ihre Anwendung beschließt, die Bohnen nach zwei Stunden reibungsloser Ausführung zu verschütten.
File "word.py", line 126, in get_stargazers_inner
for i in repo.get_stargazers_with_dates():
File "/usr/local/lib/python3.6/dist-packages/github/PaginatedList.py", line 62, in __iter__
newElements = self._grow()
File "/usr/local/lib/python3.6/dist-packages/github/PaginatedList.py", line 74, in _grow
newElements = self._fetchNextPage()
File "/usr/local/lib/python3.6/dist-packages/github/PaginatedList.py", line 199, in _fetchNextPage
headers=self.__headers
File "/usr/local/lib/python3.6/dist-packages/github/Requester.py", line 276, in requestJsonAndCheck
return self.__check(*self.requestJson(verb, url, parameters, headers, input, self.__customConnection(url)))
File "/usr/local/lib/python3.6/dist-packages/github/Requester.py", line 287, in __check
raise self.__createException(status, responseHeaders, output)
github.GithubException.RateLimitExceededException: 403 {'message': 'API rate limit exceeded for user ID xxxx.', 'documentation_url': 'https://developer.github.com/v3/#rate-limiting'}
Außerdem könnte man die Backoff-Bibliothek verwenden – sie kann jedoch die aktuelle Position in der Item-Iteration nicht berücksichtigen und beginnt daher von vorne.
Nun, ich habe https://github.com/settings/tokens besucht und ein "Token regenerieren" gemacht. Das hat mich wieder ins Rollen gebracht, aber ich weiß nicht wie lange.
Ich habe die Authentifizierungsmethode "Token" verwendet. Beispiel:
github = Github("19exxxxxxxxxxxxxxxxxxxxxe3ab065edae6470")
Siehe auch #1233 für übermäßige Anfragen.
Dieses Problem wurde automatisch als veraltet markiert, da es in letzter Zeit keine Aktivität hatte. Es wird geschlossen, wenn keine weitere Aktivität stattfindet. Vielen Dank für Ihre Beiträge.
@wangpeipei90
Bei mir funktioniert es, aber RateLimitExceededException
ist in der von mir verwendeten Version nicht unter GithubException
. Hier ist mein Code.
from github import RateLimitExceededException
issues = g.search_issues(query=keyword, **{'repo': repo, 'type': 'pr'})
iter_obj = iter(issues)
while True:
try:
pr = next(iter_obj)
with open(pr_file, 'a+') as f:
f.write(pr.html_url + '\n')
count += 1
logger.info(count)
except StopIteration:
break # loop end
except RateLimitExceededException:
search_rate_limit = g.get_rate_limit().search
logger.info('search remaining: {}'.format(search_rate_limit.remaining))
reset_timestamp = calendar.timegm(search_rate_limit.reset.timetuple())
# add 10 seconds to be sure the rate limit has been reset
sleep_time = reset_timestamp - calendar.timegm(time.gmtime()) + 10
time.sleep(sleep_time)
continue
Hier ist ein Teil des Logs:
2020/01/08 23:42:09 PM - INFO - search remaining: 0
Danke @Xiaoven Ich kann das endlich mit deinem Code lösen.
Hilfreichster Kommentar
Wenn ich das richtig verstehe, ist der Rückgabetyp von get_issues und get_pulls PaginatedList. Es verwendet
yield element
für die Iteration. Die Anfrage wird also erst beiopen_issues = [issue for issue in open_issues if issue.title not in open_pull_titles]
. Wenn Ihre Tokenlimits erreicht sind, wird die RateLimitExceedException ausgelöst.