Pygithub: github.GithubException.RateLimitExceededException

Créé le 7 mai 2019  ·  15Commentaires  ·  Source: PyGithub/PyGithub

J'essaie de récupérer le nombre de problèmes ouverts à l'aide du code suivant dans mon application Flask.

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]

et j'obtiens l'erreur github.GithubException.RateLimitExceededException: .

repo.get_issues() renvoie le nombre de problèmes ouverts plus les demandes d'extraction.

stale

Commentaire le plus utile

Si je comprends bien, le type de retour de get_issues et get_pulls est PaginatedList. Il utilise yield element pour l'itération. La requête n'est donc pas exécutée avant open_issues = [issue for issue in open_issues if issue.title not in open_pull_titles] . Si vos limites de jetons sont atteintes, l'exception RateLimitExceedException sera levée.

Tous les 15 commentaires

Si je comprends bien, le type de retour de get_issues et get_pulls est PaginatedList. Il utilise yield element pour l'itération. La requête n'est donc pas exécutée avant open_issues = [issue for issue in open_issues if issue.title not in open_pull_titles] . Si vos limites de jetons sont atteintes, l'exception RateLimitExceedException sera levée.

Y a-t-il une solution de contournement?

g = Github()
Vous êtes-vous authentifié à cette étape ? L'API publique a moins de limites de débit.

g = Github()
Vous êtes-vous authentifié à cette étape ? L'API publique a moins de limites de débit.

Oui, j'ai authentifié cette étape.

@242jainabhi
Les choses que je fais habituellement lorsque j'atteigne la limite de débit ne font que retarder le programme pendant un certain temps.

Au lieu d'utiliser la compréhension de liste, je peux utiliser simplement une boucle commune avec try-catch. Une fois qu'une exception de limite de débit est détectée, appelez la fonction sleep pour attendre un moment et vérifiez à nouveau la limite de débit avec l'API GitHub. Le code ne fonctionne que si la limite de débit revient à 5000.

Je suis désolé d'avoir raté une partie du code. Vous trouverez ci-dessous le code dans la continuité du code du premier commentaire.
J'accède à la date created_at pour tous les problèmes ouverts. Cela accédera à nouveau à l'API pour tous les problèmes et finira donc par faire des appels plus que la limite.

for issue in open_issues:
    created_at = issue.created_at.timestamp()

Je n'ai pas pu trouver de solution à ce problème. Même si j'authentifie les requêtes, la limite sera épuisée si les problèmes sont trop nombreux (disons 2000).

Quelque chose comme ça:

repositories = g.search_repositories(
    query='stars:>=10 fork:true language:python')

Déclenche également la limite de débit. Je suppose que cela fait la pagination automatiquement et que cela déclenche la limite de débit ? Y a-t-il un moyen pour moi de le faire manuellement afin que je puisse faire une pause ?

Je me rends compte maintenant que c'est un vrai problème.
Une solution de contournement possible pourrait être un extrait de code comme ci-dessous. Je ne l'ai pas encore essayé, dites-moi si cela fonctionne ou non.

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 Ne fonctionne pas.

Pour une raison quelconque, ce comportement est hautement imprévisible et exaspérant.
Mon programme peut effectivement cycler et appeler de manière préventive l'API ratelimit pour vérifier s'il respecte les limites pendant une à deux heures avant de donner au hasard un 403.

Une certaine adhésion à la limite de débit native serait la bienvenue ici. Devoir implémenter des veilles basées sur l'intuition lorsque votre application décide de renverser les choses après deux heures de fonctionnement sans heurts ne devrait pas être un comportement attendu.

 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'}

De plus, on pourrait utiliser la bibliothèque de backoff - cependant, elle ne peut pas tenir compte de la position actuelle dans l'itération de l'élément et recommencera donc à partir de zéro.

Eh bien, j'ai visité https://github.com/settings/tokens et j'ai fait un "Regenerate token". Cela m'a fait rouler à nouveau, mais je ne sais pas pour combien de temps.

J'ai utilisé la méthode d'authentification "token". Exemple:

    github = Github("19exxxxxxxxxxxxxxxxxxxxxe3ab065edae6470")

Voir aussi #1233 pour les demandes excessives.

Ce problème a été automatiquement marqué comme obsolète car il n'a pas eu d'activité récente. Il sera fermé si aucune autre activité ne se produit. Merci pour vos contributions.

@wangpeipei90

Cela fonctionne pour moi, mais le RateLimitExceededException n'est pas inférieur à GithubException dans la version que j'ai utilisée. Voici mon 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

Voici une partie du journal :

2020/01/08 23:42:09 PM - INFO - search remaining: 0

Merci, @Xiaoven, je suis enfin capable de résoudre ce problème avec votre code.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

AdyaAbhra picture AdyaAbhra  ·  5Commentaires

grayaii picture grayaii  ·  4Commentaires

surajjacob picture surajjacob  ·  4Commentaires

psychemedia picture psychemedia  ·  5Commentaires

diegotejadav picture diegotejadav  ·  5Commentaires