Pygithub: github.GithubException.RateLimitExceededException

Creado en 7 may. 2019  ·  15Comentarios  ·  Fuente: PyGithub/PyGithub

Estoy tratando de obtener la cantidad de problemas abiertos usando el siguiente código en mi aplicación 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]

y obtengo el error github.GithubException.RateLimitExceededException: .

repo.get_issues() devuelve el recuento de problemas abiertos más las solicitudes de extracción.

stale

Comentario más útil

Si lo entiendo correctamente, el tipo de retorno de get_issues y get_pulls es PaginatedList. Utiliza yield element para la iteración. Por lo tanto, la solicitud no se realiza hasta open_issues = [issue for issue in open_issues if issue.title not in open_pull_titles] . Si se alcanzan los límites de su token, lanzará la excepción RateLimitExceedException.

Todos 15 comentarios

Si lo entiendo correctamente, el tipo de retorno de get_issues y get_pulls es PaginatedList. Utiliza yield element para la iteración. Por lo tanto, la solicitud no se realiza hasta open_issues = [issue for issue in open_issues if issue.title not in open_pull_titles] . Si se alcanzan los límites de su token, lanzará la excepción RateLimitExceedException.

¿Hay algún trabajo alrededor?

g = Github()
¿Se autenticó en este paso? La API pública tiene menos límites de tasa.

g = Github()
¿Se autenticó en este paso? La API pública tiene menos límites de tasa.

Sí, autenticé ese paso.

@ 242jainabhi
Lo que suelo hacer cuando alcanzo el límite de tarifa es simplemente retrasar el programa durante algún tiempo.

En lugar de usar la comprensión de la lista, puedo usar solo un bucle común con try-catch. Una vez que se detecta una excepción de límite de frecuencia, llame a la función de suspensión para esperar un momento y vuelva a verificar el límite de frecuencia con la API de GitHub. El código solo continúa si el límite de tasa vuelve a 5000.

Lamento haber perdido una parte del código. A continuación se muestra el código en continuación del código del primer comentario.
Estoy accediendo a created_at date para todos los problemas abiertos. Esto volverá a acceder a la API para todos los problemas y, por lo tanto, terminará haciendo llamadas más allá del límite.

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

No pude encontrar una solución a este problema. Incluso si autentico las solicitudes, el límite se agotará si los problemas son demasiados (digamos 2000).

Algo como esto:

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

También activa el límite de tasa. Supongo que está haciendo la paginación automáticamente y eso está activando el límite de frecuencia. ¿Hay alguna forma de hacerlo manualmente para poder pausar?

Ahora me doy cuenta de que este es un problema real.
Una posible solución podría ser un fragmento de código como el siguiente. Aún no lo he probado, avíseme si funciona o no.

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

Por alguna razón, este comportamiento es muy impredecible y enloquecedor.
Mi programa puede realizar un ciclo de manera efectiva y llamar de manera preventiva a la api ratelimit para verificar si se adhiere dentro de los límites durante una o dos horas antes de dar aleatoriamente un 403.

Alguna adherencia al límite de la tasa nativa sería una cálida bienvenida aquí. Tener que implementar durmientes basados ​​en la intuición cuando su aplicación decide derramar los granos después de dos horas de funcionamiento sin problemas no debería ser un comportamiento esperado.

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

Además, se podría usar la biblioteca de retroceso; sin embargo, no puede tener en cuenta la posición actual en la iteración del elemento y, por lo tanto, comenzará desde cero nuevamente.

Bueno, visité https://github.com/settings/tokens e hice un "token regenerado". Eso me hizo rodar de nuevo, pero no estoy seguro de cuánto tiempo.

Usé el método de autenticación "token". Ejemplo:

    github = Github("19exxxxxxxxxxxxxxxxxxxxxe3ab065edae6470")

Vea también # 1233 para solicitudes excesivas.

Este problema se ha marcado automáticamente como obsoleto porque no ha tenido actividad reciente. Se cerrará si no se produce más actividad. Gracias por sus aportaciones.

@ wangpeipei90

Me funciona, pero RateLimitExceededException no está por debajo de GithubException en la versión que utilicé. Aquí está mi código.

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

Aquí está parte del registro:

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

Gracias, @Xiaoven . Finalmente puedo resolver esto con tu código.

¿Fue útil esta página
0 / 5 - 0 calificaciones