Pygithub: github.GithubException.RateLimitExceededException

Erstellt am 7. Mai 2019  ·  15Kommentare  ·  Quelle: PyGithub/PyGithub

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.

stale

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 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.

Alle 15 Kommentare

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.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen