λ΄ 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μ΄ λ°μν©λλ€.
ν΄κ²° λ°©λ²μ΄ μμ΅λκΉ?
g = Github()
μ΄ λ¨κ³μμ μΈμ¦νμ
¨μ΅λκΉ? κ³΅κ° APIλ μλ μ νμ΄ μ μ΅λλ€.
g = Github()
μ΄ λ¨κ³μμ μΈμ¦νμ ¨μ΅λκΉ? κ³΅κ° APIλ μλ μ νμ΄ μ μ΅λλ€.
μ, ν΄λΉ λ¨κ³λ₯Ό μΈμ¦νμ΅λλ€.
@242μμ΄λλΉ
λ΄κ° λ³΄ν΅ μλ μ νμ λλ¬νμ λ νλ μΌμ νλ‘κ·Έλ¨μ μ μ 보λ₯νλ κ²μ
λλ€.
λͺ©λ‘ μ΄ν΄λ₯Ό μ¬μ©νλ λμ try-catchμ ν¨κ» κ³΅ν΅ λ£¨νλ§ μ¬μ©ν μ μμ΅λλ€. λΉμ¨ μ ν μμΈκ° λ°μνλ©΄ sleep ν¨μλ₯Ό νΈμΆνμ¬ μ μ κΈ°λ€λ Έλ€κ° 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 μλνμ§ μμ΅λλ€.
μ΄λ€ μ΄μ μμμΈμ§ μ΄ λμμ λ§€μ° μμΈ‘ν μ μμΌλ©° λμ°ν©λλ€.
λ΄ νλ‘κ·Έλ¨μ 403μ 무μμλ‘ μ 곡νκΈ° μ μ 1~2μκ° λμ μ ν λ΄μμ μ€μνλμ§ νμΈνκΈ° μν΄ ratelimit APIλ₯Ό ν¨κ³Όμ μΌλ‘ μννκ³ μ μ μ μΌλ‘ νΈμΆν μ μμ΅λλ€.
μΌλΆ κΈ°λ³Έ μλ μ ν μ€μλ μ¬κΈ°μμ λ°λ»ν νμμ λ°μ κ²μ λλ€. μμ© νλ‘κ·Έλ¨μ΄ 2μκ° λμ μννκ² μ€νν ν λΉμ νλ¦¬κΈ°λ‘ κ²°μ ν λ μ§κ΄μ λ°λΌ μ μ λͺ¨λλ₯Ό ꡬνν΄μΌ νλ κ²μ μμλλ λμμ΄ μλλλ€.
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 λ§μΉ¨λ΄ κ·νμ μ½λλ‘ μ΄ λ¬Έμ λ₯Ό ν΄κ²°ν μ μμ΅λλ€.
κ°μ₯ μ μ©ν λκΈ
μ¬λ°λ₯΄κ² μ΄ν΄νλ©΄ get_issues λ° get_pullsμ λ°ν μ νμ PaginatedListμ λλ€. λ°λ³΅μ μν΄
yield element
λ₯Ό μ¬μ©ν©λλ€. λ°λΌμ μμ²μopen_issues = [issue for issue in open_issues if issue.title not in open_pull_titles]
κΉμ§ μνλμ§ μμ΅λλ€. ν ν° μ νμ λλ¬νλ©΄ RateLimitExceedExceptionμ΄ λ°μν©λλ€.