API GitHub ΠΎΠ³ΡΠ°Π½ΠΈΡΠΈΠ²Π°Π΅Ρ ΠΏΠΎΠΈΡΠΊ Π΄ΠΎ 1000 ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ² . ΠΡΠΎ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ Π²Π»ΠΈΡΠ΅Ρ Π½Π° ΠΏΠΎΠΈΡΠΊ, Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ΡΠ΅ΡΠ΅Π· PyGitHub, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ GitHub.search_issues .
ΠΠΎΡ ΠΎΠΆΠ΅, Π½Π΅Ρ Π½ΠΈΠΊΠ°ΠΊΠΈΡ ΠΏΡΠΈΠ·Π½Π°ΠΊΠΎΠ² ΡΠΎΠ³ΠΎ, ΡΡΠΎ Π²Π°Ρ ΠΏΠΎΠΈΡΠΊ Π΄ΠΎΡΡΠΈΠ³ ΡΡΠΎΠ³ΠΎ ΠΏΡΠ΅Π΄Π΅Π»Π° - Ρ Π½Π΅ Π·Π½Π°Ρ Π½ΠΈΠΊΠ°ΠΊΠΈΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠΉ ΠΈΠ»ΠΈ ΠΎΡΠΈΠ±ΠΎΠΊ. ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΠΊΠΎΠ³Π΄Π° ΡΡΠΎ ΠΏΡΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ, Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡΡΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ (Π΅ΡΠ»ΠΈ ΠΎΠ½ΠΎ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΎ).
ΠΠΎΠΆΠ½ΠΎ ΠΎΠ±ΠΎΠΉΡΠΈ ΡΡΠΎ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅, Π²ΡΠΏΠΎΠ»Π½ΠΈΠ² Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΏΠΎΠΈΡΠΊΠΎΠ²ΡΡ Π·Π°ΠΏΡΠΎΡΠΎΠ², Π½ΠΎ ΡΠ°ΠΊΠΈΠ΅ Π·Π°ΠΏΡΠΎΡΡ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ Π°Π΄Π°ΠΏΡΠΈΡΠΎΠ²Π°Π½Ρ ΠΊ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΠΌ ΡΠ΅Π»ΡΠΌ Π·Π°ΠΏΡΠΎΡΠ° - Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΏΠΎΠ²ΡΠΎΡΠ΅Π½ΠΈΠ΅ search_issues ΠΏΠΎ ΠΏΡΠΎΠ³ΡΠ΅ΡΡΠΈΠ²Π½ΡΠΌ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π°ΠΌ Π΄Π°Ρ - ΠΈ Ρ Π½Π΅ ΠΌΠΎΠ³Ρ ΠΏΡΠΈΠ΄ΡΠΌΠ°ΡΡ ΡΠΏΠΎΡΠΎΠ± ΠΎΠ±ΠΎΠ±ΡΠΈΡΡ ΡΡΠΎ.
ΠΡΡΡ ΠΌΡΡΠ»ΠΈ ΠΎ ΡΠΎΠΌ, ΠΊΠ°ΠΊ Ρ ΡΡΠΈΠΌ ΡΠΏΡΠ°Π²ΠΈΡΡΡΡ? ΠΡΡΡ Π»ΠΈ ΠΎΠ±ΡΠ΅Π΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅?
ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΡΡΠΎ ΡΡΠ° ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ Π½ΠΈΡΠ΅Π³ΠΎ ΠΎΠ±ΡΠ΅Π³ΠΎ Ρ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ΠΌ ΡΠΊΠΎΡΠΎΡΡΠΈ ΠΈΠ»ΠΈ ΡΠ°Π·Π±ΠΈΠ΅Π½ΠΈΠ΅ΠΌ Π½Π° ΡΡΡΠ°Π½ΠΈΡΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ².
ΠΠΎΡ ΠΎΠ±Ρ ΠΎΠ΄Π½ΠΎΠΉ ΠΏΡΡΡ, Π΄Π΅ΠΌΠΎΠ½ΡΡΡΠΈΡΡΡΡΠΈΠΉ, ΠΊΠ°ΠΊ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π²ΡΠ΅ Π·Π°ΠΏΡΠΎΡΡ Π½Π° Π²ΡΡΡΠ³ΠΈΠ²Π°Π½ΠΈΠ΅ Π² Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π΅ Π΄Π°Ρ, Π΄Π°ΠΆΠ΅ Π΅ΡΠ»ΠΈ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ² Π±ΠΎΠ»Π΅Π΅ 1000:
Π ΠΠΠΠΠ’ΠΠ ΠΠΠΠ’Π¬: Ρ ΠΏΠ΅ΡΠ΅ΠΏΠΈΡΡ ΡΡΠΎ ΠΊΠ°ΠΊ ΠΌΠ΅ΡΠΎΠ΄, ΠΊΠΎΡΠΎΡΡΠΉ Π΄Π°Π΅Ρ, Π° Π½Π΅ ΠΊΠ»Π°ΡΡ, Π±ΡΠ΄Π΅Ρ ΠΏΡΠΎΡΠ΅
class PullRequestQuery:
def __init__(self, git, repo, since, until):
self.git = git
self.repo = repo
self.until = until
self.issues = self.__query(since, until)
def __iter__(self):
skip = False
while True:
results = False
for issue in self.issues:
if not skip:
results = True
yield issue.as_pull_request()
skip = False
# If no more results then stop iterating.
if not results:
break
# Start new query picking up where we left off. Previous issue will be first one returned, so skip it.
self.issues = self.__query(issue.closed_at.strftime('%Y-%m-%dT%H:%M:%SZ'), self.until)
skip = True
def __query(self, since, until):
querystring = 'type:pr is:closed repo:%s/%s closed:"%s..%s"' % (self.repo.organization.login, self.repo.name, since, until)
return self.git.search_issues(query=querystring, sort="updated", order="asc")
Π’Π΅ΠΏΠ΅ΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΡΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ° Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π΅Π»Π°ΡΡ ΡΠ°ΠΊΠΈΠ΅ Π²Π΅ΡΠΈ:
git = Github(user, passwd)
org = git.get_organization(orgname)
repo = org.get_repo(reponame)
for pull in PullRequestQuery(git, repo, "2017-01-01", "2017-12-31"):
print "%s: %s" % (pull.number, pull.title)
Π§ΠΈΡΠ°Ρ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΡ Github API ΠΎ ΠΏΠΎΠΈΡΠΊΠ΅, Ρ ΡΠ°ΠΊΠΆΠ΅ Π·Π°ΠΌΠ΅ΡΠΈΠ», ΡΡΠΎ incomplete_results
ΠΎΡΡΡΡΡΡΠ²ΡΠ΅Ρ ΠΊΠ°ΠΊ ΡΠ°ΡΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ² ΠΏΠΎΠΈΡΠΊΠ° Π² PyGithub. ΠΠ΅ΡΠΎΡΡΠ½ΠΎ, Π²ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΡΡΠΎΠ³ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΡΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΠΌΠΎΡΡ Π² ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ ΡΠΎΠ³ΠΎ, ΠΌΠΎΠ³ΡΡ Π»ΠΈ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ ΠΏΠΎΠΈΡΠΊΠ° Π±ΡΡΡ (Π½Π΅ΠΏΠΎΠ»Π½ΡΠΌΠΈ).
Π’Π΅ΠΏΠ΅ΡΡ, ΠΊΠΎΠ³Π΄Π° Ρ ΠΌΠ΅Π½Ρ Π΅ΡΡΡ ΡΠ°Π·Π²Π΅ΡΠ²Π»Π΅Π½Π½ΡΠΉ PyGithub ΠΈ ΡΠ°Π±ΠΎΡΠ°ΡΡΠΈΠΉ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ ΠΈΠ· ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° (Ρ ΡΠΌΠΎΡΡΡ Π½Π° β 606), Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Ρ ΡΠΌΠΎΠ³Ρ ΠΈΡΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΡ ΡΡΠΎ Π΄Π°Π»ΡΡΠ΅.
ΠΡΠ° ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° Π±ΡΠ»Π° Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΏΠΎΠΌΠ΅ΡΠ΅Π½Π° ΠΊΠ°ΠΊ ΡΡΡΠ°ΡΠ΅Π²ΡΠ°Ρ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π² ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅Π΅ Π²ΡΠ΅ΠΌΡ Π½Π΅ Π±ΡΠ»ΠΎ Π°ΠΊΡΠΈΠ²Π½ΠΎΡΡΠΈ. ΠΠ½ Π±ΡΠ΄Π΅Ρ Π·Π°ΠΊΡΡΡ, Π΅ΡΠ»ΠΈ Π±ΠΎΠ»ΡΡΠ΅ Π½Π΅ Π±ΡΠ΄Π΅Ρ Π°ΠΊΡΠΈΠ²Π½ΠΎΡΡΠΈ. Π‘ΠΏΠ°ΡΠΈΠ±ΠΎ Π·Π° Π²Π°Ρ Π²ΠΊΠ»Π°Π΄.
ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎ ΠΎΡΠΊΡΡΡΡ ΡΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ?
Π° ΡΠ°ΠΊΠΆΠ΅ Π΄Π»Ρ ΠΎΠ±ΡΠ΅Π³ΠΎ ΡΠ΅ΡΠ΅Π½ΠΈΡ Π΄Π»Ρ Π΄ΡΡΠ³ΠΈΡ
Π·Π°ΠΏΡΠΎΡΠΎΠ²
Π‘Π°ΠΌΡΠΉ ΠΏΠΎΠ»Π΅Π·Π½ΡΠΉ ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠΉ
ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎ ΠΎΡΠΊΡΡΡΡ ΡΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ?
Π° ΡΠ°ΠΊΠΆΠ΅ Π΄Π»Ρ ΠΎΠ±ΡΠ΅Π³ΠΎ ΡΠ΅ΡΠ΅Π½ΠΈΡ Π΄Π»Ρ Π΄ΡΡΠ³ΠΈΡ Π·Π°ΠΏΡΠΎΡΠΎΠ²