ΠΠΎΡ ΠΎΠΆΠ΅, ΡΡΠΎ ΡΡΠ½ΠΊΡΠΈΡ get_rate_limit Π²Π΅ΡΠ½Π΅Ρ ΡΠΎ, ΡΡΠΎ Github ΡΡΠΈΡΠ°Π΅Ρ Β«ΠΎΡΠ½ΠΎΠ²Π½ΡΠΌΒ» ΠΏΡΠ΅Π΄Π΅Π»ΠΎΠΌ ΡΠΊΠΎΡΠΎΡΡΠΈ. ΠΠ΄Π½Π°ΠΊΠΎ ΡΡΡΠ΅ΡΡΠ²ΡΡΡ ΡΠ°Π·Π½ΡΠ΅ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ ΡΠΊΠΎΡΠΎΡΡΠΈ ΠΏΠΎΠΈΡΠΊΠ° ΠΊΠΎΠ΄Π°. Π‘ΠΌΠΎΡΡΠΈΡΠ΅ Π·Π΄Π΅ΡΡ .
ΠΠ°ΡΠΊΠΎΠ»ΡΠΊΠΎ Ρ ΠΌΠΎΠ³Ρ ΡΡΠ΄ΠΈΡΡ, ΡΠ΅ΠΉΡΠ°Ρ Π½Π΅Ρ ΡΠΏΠΎΡΠΎΠ±Π° ΠΏΠΎΠ»ΡΡΠΈΡΡ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ ΡΠΊΠΎΡΠΎΡΡΠΈ ΠΊΠΎΠ΄Π° ΠΏΠΎΠΈΡΠΊΠ°.
Π― Π²ΠΈΠΆΡ ΡΡ ΠΆΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ. ΠΠΎΡ Π½Π΅Π±ΠΎΠ»ΡΡΠΎΠΉ ΡΠΊΡΠΈΠΏΡ, ΠΈΠ»Π»ΡΡΡΡΠΈΡΡΡΡΠΈΠΉ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ.
import os
from datetime import datetime
from github import Github
# Login
TOKEN = os.getenv("GITHUB_ACCESS_TOKEN")
github = Github(TOKEN)
# Get initial rate limit and reset time
rl1 = github.get_rate_limit().rate
print("RL1 | Limit: {}, Remaining: {}, Reset: {}.".format(
rl1.limit, rl1.remaining, rl1.reset))
# RL1 | Limit: 5000, Remaining: 5000, Reset: 2017-09-22 17:26:35.
# Perform a search
results = github.search_code("Hello World")
# Rate limit of Github instance is unchanged after a search
rl2 = github.get_rate_limit().rate
print("RL2 | Limit: {}, Remaining: {}, Reset: {}.".format(
rl2.limit, rl2.remaining, rl2.reset))
# RL2 | Limit: 5000, Remaining: 5000, Reset: 2017-09-22 17:26:35.
# The PaginatedList instance has a Requestor with the same info
rl3 = results._PaginatedList__requester.rate_limiting
rl3_reset = datetime.utcfromtimestamp(int(
results._PaginatedList__requester.rate_limiting_resettime))
print("RL3 | Limit: {}, Remaining: {}, Reset: {}.".format(
rl3[0], rl3[1], rl3_reset))
# RL3 | Limit: 5000, Remaining: 5000, Reset: 2017-09-22 17:26:35.
# However, the actual ContentFile results show a different limit
# The Requester of each individual result ...
result = results[0]
rl4 = result._requester.rate_limiting
rl4_reset = datetime.utcfromtimestamp(int(
result._requester.rate_limiting_resettime))
print("RL4 | Limit: {}, Remaining: {}, Reset: {}.".format(
rl4[1], rl4[0], rl4_reset))
# RL4 | Limit: 30, Remaining: 29, Reset: 2017-09-22 16:27:36.
# ... and headers stored in the content file directly show a different rate limit.
rl5_limit = result._headers['x-ratelimit-limit']
rl5_remaining = result._headers['x-ratelimit-remaining']
rl5_reset = datetime.utcfromtimestamp(int(
result._headers['x-ratelimit-reset']))
print("RL5 | Limit: {}, Remaining: {}, Reset: {}.".format(
rl5_limit, rl5_remaining, rl5_reset))
# RL5 | Limit: 30, Remaining: 29, Reset: 2017-09-22 16:27:36.
# In the end, the main Github instance still shows the original full rate limit
rl6 = github.get_rate_limit().rate
print("RL6 | Limit: {}, Remaining: {}, Reset: {}.".format(
rl6.limit, rl6.remaining, rl6.reset))
# RL6 | Limit: 5000, Remaining: 5000, Reset: 2017-09-22 17:26:35.
+1 ΠΡΠ° ΡΡΠ½ΠΊΡΠΈΡ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠ° Π΄Π»Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΠΎΠ΅ Ρ ΠΏΡΡΠ°ΡΡΡ ΡΠΎΠ·Π΄Π°ΡΡ.
@brentshermana Π΄Π»Ρ Π²Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, ΡΠ°ΡΡΠΌΠΎΡΡΠΈΡΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ ΡΠΊΠΎΡΠΎΡΡΠΈ (ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅Π³ΠΎ ΠΎΡΠ²Π΅ΡΠ°; ΡΠΌ. ΠΠΎΠΉ ΠΏΡΠΈΠΌΠ΅Ρ Π²ΡΡΠ΅) ΠΈΠ»ΠΈ ΡΠ°ΠΌΠΎΡΡΠΎΡΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ ΠΎΠΏΡΠΎΡΠ° ΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΉ ΡΠΎΡΠΊΠΈ /rate_limit
. ΠΡΠΎ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎΠ±ΠΎ Π²ΡΠ΅Ρ
Π²ΠΈΠ΄Π°Ρ
ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠΉ ΡΠΊΠΎΡΠΎΡΡΠΈ ΠΈ Π½Π΅ Π·Π°ΡΡΠΈΡΡΠ²Π°Π΅ΡΡΡ Π² ΠΊΠ°ΠΊΠΎΠ΅-Π»ΠΈΠ±ΠΎ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ ΡΠΊΠΎΡΠΎΡΡΠΈ.
Π ΠΊΠΎΠ½ΡΠ΅ ΠΊΠΎΠ½ΡΠΎΠ², Π±ΡΠ»ΠΎ Π±Ρ Π½Π΅ΠΏΠ»ΠΎΡ
ΠΎ, Π΅ΡΠ»ΠΈ Π±Ρ PyGithub Π½Π΅ ΡΠΎΠ»ΡΠΊΠΎ Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°Π» rate
, Π½ΠΎ ΠΈ Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°Π» resources
ΠΈΠ· ΡΠΎΠ³ΠΎ, ΡΡΠΎ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ /rate_limit
. ΠΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π΅ΡΡΡ, ΠΊ ΡΠΎΠΆΠ°Π»Π΅Π½ΠΈΡ, ΠΎΠ½Π° Π½Π΅ Π΄ΠΎΡΡΡΠΏΠ½Π° Π΄Π»Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ.
ΠΡΠΎΠΌΠ΅ ΡΠΎΠ³ΠΎ, ΡΠΏΠΈΡΠΎΠΊ Ρ ΡΠ°Π·Π±ΠΈΠ²ΠΊΠΎΠΉ Π½Π° ΡΡΡΠ°Π½ΠΈΡΡ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ ΡΠΊΠΎΡΠΎΡΡΠΈ ΠΏΠΎΠΈΡΠΊΠ° ΠΏΠΎ ΠΊΠΎΠ΄Ρ, Π΅ΡΠ»ΠΈ ΠΎΠ½ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ ΡΠ°ΠΊΠΎΠ³ΠΎ ΠΏΠΎΠΈΡΠΊΠ°, ΡΠΎ Π΅ΡΡΡ Π²ΡΠ΅, ΡΡΠΎ Ρ
ΡΠ°Π½ΠΈΡΡΡ Π² _headers['x-ratelimit-*']
.
ΠΡΡΠ°ΡΠΈ: Ρ ΡΠΎΠ»ΡΠΊΠΎ ΡΡΠΎ Π·Π°ΠΌΠ΅ΡΠΈΠ», ΡΡΠΎ ΠΏΠΎΠ»Π΅ rate
ΠΈΠ· JSON, Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΠΎΠ΅ /rate_limit
, ΡΡΡΠ°ΡΠ΅Π»ΠΎ, Π° ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π² resources
ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΠΌΠΎΠΉ Π°Π»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²ΠΎΠΉ: https://developer.github.com/ v3/rate_limit/#deprecation -ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅
Π― Π΄Π΅Π»Π°Ρ ΠΈΠΌΠ΅Π½Π½ΠΎ ΡΡΠΎ. ΠΡΠ»ΠΈ ΠΊΡΠΎ-ΡΠΎ Ρ ΠΎΡΠ΅Ρ Π°Π΄Π°ΠΏΡΠΈΡΠΎΠ²Π°ΡΡ ΡΡΠΎ ΠΈ ΠΏΠΎΠΏΡΡΠ°ΡΡΡΡ ΡΠ΄Π΅Π»Π°ΡΡ Π·Π°ΠΏΡΠΎΡ Π½Π° Π²ΡΡΡΠ³ΠΈΠ²Π°Π½ΠΈΠ΅, Ρ Π±Π»Π°Π³ΠΎΡΠ»ΠΎΠ²Π»ΡΡ Π²Π°Ρ:
def wait(seconds):
print("Waiting for {} seconds ...".format(seconds))
time.sleep(seconds)
print("Done waiting - resume!")
def api_wait():
url = 'https://api.github.com/rate_limit'
response = urlopen(url).read()
data = json.loads(response.decode())
if data['resources']['core']['remaining'] <= 10: # extra margin of safety
reset_time = data['resources']['core']['reset']
wait(reset_time - time.time() + 10)
elif data['resources']['search']['remaining'] <= 2:
reset_time = data['resources']['search']['reset']
wait(reset_time - time.time() + 10)
Π― ΡΡΠΎΠ»ΠΊΠ½ΡΠ»ΡΡ Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΎΠΉ, ΠΊΠΎΠ³Π΄Π° ΠΌΠΎΡ ΠΈΡΠ΅ΡΠ°ΡΠΈΡ ΠΏΠΎ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ°ΠΌ search_issues ΠΎΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ ΠΏΠΎΡΠ»Π΅ 1020 ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ², ΠΊΠΎΠ³Π΄Π° Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡΡΡ 1869 ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ². ΠΠΎΠΉ ΡΠΊΡΠΈΠΏΡ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π· ΠΎΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΈ ΡΠΎΠΌ ΠΆΠ΅ ΠΌΠ΅ΡΡΠ΅. ΠΠΎΠΆΠ΅Ρ Π»ΠΈ ΡΡΠΎ Π±ΡΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΎΠΉ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ ΡΠΊΠΎΡΠΎΡΡΠΈ?
Π― Π½Π΅ ΠΏΠΎΠ»ΡΡΠ°Ρ ΠΎΡΠΈΠ±ΠΊΡ, ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ ΠΏΡΠΎΡΡΠΎ Π·Π°ΠΊΠ°Π½ΡΠΈΠ²Π°ΡΡΡΡ. ΠΡΠ»ΠΈ Ρ ΠΏΠΎΠΌΠ΅ΡΡ ΡΠ²ΠΎΡ ΡΡΡΠΎΠΊΡ Π·Π°ΠΏΡΠΎΡΠ° Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ Π² Π²Π΅Π±-ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ GitHub, Ρ ΡΠ²ΠΈΠΆΡ Π²ΡΠ΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ 1869, ΠΊΠ°ΠΊ ΠΈ ΠΎΠΆΠΈΠ΄Π°Π»ΠΎΡΡ. 1020 ΠΊΡΠ°ΡΠ½ΠΎ 30, ΡΡΠΎ Π·Π°ΡΡΠ°Π²Π»ΡΠ΅Ρ ΠΌΠ΅Π½Ρ Π·Π°Π΄ΡΠΌΠ°ΡΡΡΡ, Π½Π΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° Π»ΠΈ ΡΡΠΎ Ρ Π½ΡΠΌΠ΅ΡΠ°ΡΠΈΠ΅ΠΉ ΡΡΡΠ°Π½ΠΈΡ?
ΠΠΎΠ΄ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
querystring = "type:pr is:closed repo:xxxx closed:2017-07-01..2018-06-30"
issues = git.search_issues(query=querystring, sort="updated", order="asc")
for issue in issues:
pull = issue.as_pull_request()
print "%s: %s" % (pull.number, pull.title)
ΠΠΎΠ»ΡΡΠΎΠ΅ ΡΠΏΠ°ΡΠΈΠ±ΠΎ Π·Π° Π»ΡΠ±ΡΠ΅ ΡΠΎΠ²Π΅ΡΡ, ΠΊΠΎΡΠΎΡΡΠΌΠΈ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΠΎΠ΄Π΅Π»ΠΈΡΡΡΡ, ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΡΠΎΠ³ΠΎ, ΡΡΠΎ Π·Π΄Π΅ΡΡ ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΠΉΡΠΈ Π½Π΅ ΡΠ°ΠΊ.
Π― ΡΠ°ΠΊΠΆΠ΅ ΠΏΠΎΠΏΡΡΠ°Π»ΡΡ ΠΏΠΎΠ²ΡΠΎΡΠΈΡΡ issues.reversed
, ΡΡΠΎΠ±Ρ ΡΠ²ΠΈΠ΄Π΅ΡΡ, Π½Π°ΡΠ½Π΅ΡΡΡ Π»ΠΈ ΠΎΠ½ Π² ΠΊΠΎΠ½ΡΠ΅ ΠΌΠΎΠΈΡ
ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΡΡ
ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ² 1869. ΠΠ΄Π½Π°ΠΊΠΎ Π² ΡΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Ρ ΠΏΠΎΠ»ΡΡΠ°Ρ ΡΠΎΠ»ΡΠΊΠΎ 30 Π²ΠΎΠΏΡΠΎΡΠΎΠ² Ρ ΠΏΠ΅ΡΠ²ΠΎΠΉ ΡΡΡΠ°Π½ΠΈΡΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ².
ΠΠ°Π»ΡΠ½Π΅ΠΉΡΠ΅Π΅ ΡΠ°ΡΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎΠΊΠ°Π·Π°Π»ΠΎ, ΡΡΠΎ Ρ ΡΠΏΠΈΡΠ°ΡΡΡ Π² 1000 ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ² Π½Π° ΠΏΠΎΠΈΡΠΊΠΎΠ²ΡΠΉ Π»ΠΈΠΌΠΈΡ .
ΠΠ°ΠΊ Π½Π°ΡΡΠ΅Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΠΌΡ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²ΠΈΠ»ΠΈ Π΅ΡΠ΅ ΠΎΠ΄ΠΈΠ½ ΠΌΠ΅ΡΠΎΠ΄ get_search_rate_limit()
Π΄Π»Ρ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ ΡΠΊΠΎΡΠΎΡΡΠΈ ΠΏΠΎΠΈΡΠΊΠ°, Π² ΡΠΎ Π²ΡΠ΅ΠΌΡ ΠΊΠ°ΠΊ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠΈΠΉ get_rate_limit()
Π±ΡΠ΄Π΅Ρ Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅Π΅ Β«ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠ΅Β» ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ ΡΠΊΠΎΡΠΎΡΡΠΈ, ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ΅ Github: https://developer.github.com/ v3/rate_limit/
ΠΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ ΡΠΊΠΎΡΠΎΡΡΠΈ ΠΏΠΎΠΈΡΠΊΠ° API ΠΈ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ ΡΠΊΠΎΡΠΎΡΡΠΈ GraphQL ΡΠΆΠ΅ Π΄ΠΎΡΡΡΠΏΠ½Ρ. ΠΠ΄ΠΈΠ½ ΠΌΠ΅ΡΠΎΠ΄ Π΄Π»Ρ Π²ΡΠ΅Ρ .
ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ ΠΎΠ½ ΠΏΠΎΠΊΠ°ΠΆΠ΅Ρ Π²Π°ΠΌ Β«ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉΒ» ΠΏΡΠ΅Π΄Π΅Π» ΡΠΊΠΎΡΠΎΡΡΠΈ. ΠΡ ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ ΡΠΊΠΎΡΠΎΡΡΠΈ ΠΏΠΎΠΈΡΠΊΠ°/Π³ΡΠ°ΡΠΈΠΊΠ°, ΠΎΠ±ΡΠ°ΡΠΈΠ²ΡΠΈΡΡ ΠΊ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΌ Π°ΡΡΠΈΠ±ΡΡΠ°ΠΌ.
r = g.get_rate_limit()
>>> r
RateLimit(core=Rate(remaining=4923, limit=5000))
>>> r.search
Rate(remaining=30, limit=30)
>>> r.graphql
Rate(remaining=5000, limit=5000)
ΠΡΠ³Π»ΡΠ΄ΠΈΡ ΠΎΡΠ»ΠΈΡΠ½ΠΎ, ΡΠΏΠ°ΡΠΈΠ±ΠΎ @sfdye!
Π§ΡΠΎΠ±Ρ ΡΠΌΡΠ»ΠΈΡΠΎΠ²Π°ΡΡ ΡΡΠ½ΠΊΡΠΈΡ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ @brentshermana , ΡΡΠΎΠ±Ρ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌ Ρ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ΠΌ ΡΠΊΠΎΡΠΎΡΡΠΈ ΠΏΠΎΠΈΡΠΊΠ°, ΡΠ΅ΠΏΠ΅ΡΡ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠ΄Π΅Π»Π°ΡΡ ΡΡΠΎ-ΡΠΎ Π²ΡΠΎΠ΄Π΅ ΡΡΠΎΠ³ΠΎ:
from datetime import datetime
def api_wait_search(git):
limits = git.get_rate_limit()
if limits.search.remaining <= 2:
seconds = (limits.search.reset - datetime.now()).total_seconds()
print "Waiting for %d seconds ..." % (seconds)
time.sleep(seconds)
print "Done waiting - resume!"
ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΡΡΠΎ Π²ΡΠ·ΠΎΠ² get_rate_limit()
Π²ΡΠ·ΠΎΠ²Π΅Ρ Π½Π΅Π±ΠΎΠ»ΡΡΡΡ Π·Π°Π΄Π΅ΡΠΆΠΊΡ, ΠΏΠΎΡΡΠΎΠΌΡ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠ²Π΅ΡΡΠΈ ΠΊ ΠΌΠΈΠ½ΠΈΠΌΡΠΌΡ ΡΠ°ΡΡΠΎΡΡ Π΅Π³ΠΎ Π²ΡΠ·ΠΎΠ²Π°.
ΠΠ»Ρ Π»ΡΠ΄Π΅ΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΏΠΎΠΏΠ°Π΄Π°ΡΡ ΡΡΠ΄Π° ΠΈΠ· ΠΏΠΎΠΈΡΠΊΠΎΠ²ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΡ, Ρ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ» ΡΡΠ½ΠΊΡΠΈΡ @bbi-yggy:
from datetime import datetime, timezone
def rate_limited_retry(github):
def decorator(func):
def ret(*args, **kwargs):
for _ in range(3):
try:
return func(*args, **kwargs)
except RateLimitExceededException:
limits = github.get_rate_limit()
reset = limits.search.reset.replace(tzinfo=timezone.utc)
now = datetime.now(timezone.utc)
seconds = (reset - now).total_seconds()
print(f"Rate limit exceeded")
print(f"Reset is in {seconds:.3g} seconds.")
if seconds > 0.0:
print(f"Waiting for {seconds:.3g} seconds...")
time.sleep(seconds)
print("Done waiting - resume!")
raise Exception("Failed too many times")
return ret
return decorator
ΠΡΡ ΡΡΠ½ΠΊΡΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
@rate_limited_retry(github)
def run_query(import_string):
query_string = f"language:Python \"{import_string}\""
return list(github.search_code(query_string))
results = run_query(import_string)
ΠΠΎΠ΄ΠΈΡΠΈΡΠΈΡΠΎΠ²Π°Π½Π½Π°Ρ Π²Π΅ΡΡΠΈΡ Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡΠ° pokey Π²ΡΡΠ΅, ΡΡΠΎΠ±Ρ ΡΡΠ΅ΡΡΡ core/search/graphql.
Π’Π°ΠΊΠΆΠ΅ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π° ββ30-ΡΠ΅ΠΊΡΠ½Π΄Π½Π°Ρ Π·Π°Π΄Π΅ΡΠΆΠΊΠ°, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ Github Π½Π΅ ΡΠ±ΡΠ°ΡΡΠ²Π°Π΅Ρ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ ΡΠΊΠΎΡΠΎΡΡΠΈ ΡΠΎΡΠ½ΠΎ Π² ΡΠΊΠ°Π·Π°Π½Π½ΠΎΠ΅ Π²ΡΠ΅ΠΌΡ.
def rate_limited_retry():
def decorator(func):
def ret(*args, **kwargs):
for _ in range(3):
try:
return func(*args, **kwargs)
except RateLimitExceededException:
limits = gh.get_rate_limit()
print(f"Rate limit exceeded")
print("Search:", limits.search, "Core:", limits.core, "GraphQl:", limits.graphql)
if limits.search.remaining == 0:
limited = limits.search
elif limits.graphql.remaining == 0:
limited = limits.graphql
else:
limited = limits.core
reset = limited.reset.replace(tzinfo=timezone.utc)
now = datetime.now(timezone.utc)
seconds = (reset - now).total_seconds() + 30
print(f"Reset is in {seconds} seconds.")
if seconds > 0.0:
print(f"Waiting for {seconds} seconds...")
time.sleep(seconds)
print("Done waiting - resume!")
raise Exception("Failed too many times")
return ret
return decorator
Π‘Π°ΠΌΡΠΉ ΠΏΠΎΠ»Π΅Π·Π½ΡΠΉ ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠΉ
ΠΠ»Ρ Π»ΡΠ΄Π΅ΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΏΠΎΠΏΠ°Π΄Π°ΡΡ ΡΡΠ΄Π° ΠΈΠ· ΠΏΠΎΠΈΡΠΊΠΎΠ²ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΡ, Ρ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ» ΡΡΠ½ΠΊΡΠΈΡ @bbi-yggy:
ΠΡΡ ΡΡΠ½ΠΊΡΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ: