Pygithub: github.GithubException.RateLimitExceededException

Созданный на 7 мая 2019  ·  15Комментарии  ·  Источник: PyGithub/PyGithub

Я пытаюсь получить количество открытых проблем, используя следующий код в моем приложении 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]

и я получаю сообщение об ошибке github.GithubException.RateLimitExceededException: .

repo.get_issues() возвращает количество открытых проблем плюс запросы на вытягивание.

Самый полезный комментарий

Если я правильно понимаю, возвращаемый тип get_issues и get_pulls - PaginatedList. Для итерации используется yield element . Таким образом, запрос не выполняется до open_issues = [issue for issue in open_issues if issue.title not in open_pull_titles] . Если ваши ограничения на токены достигнуты, он вызовет исключение RateLimitExceedException.

Все 15 Комментарий

Если я правильно понимаю, возвращаемый тип get_issues и get_pulls - PaginatedList. Для итерации используется yield element . Таким образом, запрос не выполняется до open_issues = [issue for issue in open_issues if issue.title not in open_pull_titles] . Если ваши ограничения на токены достигнуты, он вызовет исключение RateLimitExceedException.

Есть ли обходной путь?

g = Github()
Вы прошли аутентификацию на этом этапе? public api имеет меньшие ограничения скорости.

g = Github()
Вы прошли аутентификацию на этом этапе? public api имеет меньшие ограничения скорости.

Да, я подтвердил этот шаг.

@ 242jainabhi
То, что я обычно делаю при достижении лимита скорости, просто откладываю программу на некоторое время.

Вместо использования понимания списка я могу использовать обычный цикл с try-catch. После обнаружения исключения ограничения скорости вызовите функцию сна, чтобы немного подождать и снова проверить ограничение скорости с помощью GitHub API. Код работает только в том случае, если ограничение скорости возвращается к 5000.

Прошу прощения за отсутствие части кода. Ниже приведен код, продолжающий код в первом комментарии.
Я получаю доступ к дате created_at для всех открытых вопросов. Это снова позволит получить доступ к API для всех проблем и, следовательно, в конечном итоге будет совершать больше вызовов, чем установлено.

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

Я не мог найти решения этой проблемы. Даже если я аутентифицирую запросы, лимит будет исчерпан, если проблем будет слишком много (скажем, 2000).

Что-то вроде этого:

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

Также срабатывает ограничение скорости. Я предполагаю, что он автоматически разбивает страницы и запускает ограничение скорости? Есть ли способ сделать это вручную, чтобы я мог сделать паузу?

Теперь я понимаю, что это реальная проблема.
Одним из возможных решений может быть фрагмент кода, подобный приведенному ниже. Еще не пробовал, дайте знать, работает или нет.

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 Не работает.

По какой-то причине такое поведение крайне непредсказуемо и сводит с ума.
Моя программа может эффективно циклически повторять и предварительно вызывать api ratelimit, чтобы проверить, придерживается ли он установленных лимитов в течение одного-двух часов, прежде чем случайным образом выдаст ошибку 403.

Здесь мы будем тепло приветствовать соблюдение некоторых собственных ограничений скорости. Не следует ожидать, что вам придется реализовывать спящий режим на основе интуиции, когда ваше приложение решает пролить свет после двух часов бесперебойной работы.

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

Кроме того, можно использовать библиотеку отката - однако она не может учитывать текущую позицию в итерации элемента и поэтому снова будет начинать с нуля.

Ну, я зашел на https://github.com/settings/tokens и сделал «Регенерировать токен». Это снова заставило меня кататься, но я не уверен, как долго.

Я использовал «токен» аутентификации. Пример:

    github = Github("19exxxxxxxxxxxxxxxxxxxxxe3ab065edae6470")

См. Также # 1233 для чрезмерных запросов.

Эта проблема была автоматически помечена как устаревшая, поскольку в последнее время не было активности. Он будет закрыт, если больше не будет активности. Спасибо за ваш вклад.

@ wangpeipei90

У меня это работает, но RateLimitExceededException не ниже GithubException в той версии, которую я использовал. Вот мой код.

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

Вот часть журнала:

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

Спасибо, @Xiaoven, я наконец могу решить эту проблему с помощью вашего кода.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги