Pygithub: github.PaginatedList.PaginatedList totalCount ๋ฐ˜ํ™˜ ์—†์Œ

์— ๋งŒ๋“  2016๋…„ 07์›” 02์ผ  ยท  14์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: PyGithub/PyGithub

๋‚ด ์งˆ๋ฌธ์€ ์™œ totalCount๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•˜๋ฉด None์ด ๋ฐ˜ํ™˜๋˜์ง€๋งŒ iterate๋Š” ์ˆซ์ž๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

            repo_commits = repo.get_commits()
            repo_total = 0
            for _ in repo_commits:
                repo_total = repo_total + 1
            repo_total = repo.get_commits().totalCount

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์š”์ :

    from github import Github
    gh = Github()
    gists = gh.get_user('gil9red').get_gists()
    print(gists.totalCount)  # None
    print(len(list(gists)))  # 7

๋ชจ๋“  14 ๋Œ“๊ธ€

๋‚ด ์ฝ”๋“œ๋ฅผ ๋ถ™์—ฌ๋„ฃ์Šต๋‹ˆ๋‹ค

import json
import os

import github
from github import Github

# First create a Github instance:

g = Github("grapebaba", "heatonn1",per_page=1000)


def main():
    '''
    Use small data for this application
    :return:
    '''
    with open(os.path.join(os.path.expanduser("~"),'recruitbot_data.txt'),'w') as f:
        for user in g.search_users("type:user")[0:10000]:
            user_dict = {}
            user_dict['username'] = user.login
            user_dict['id'] = user.id
            user_dict['profile_url'] = user.html_url
            user_dict['location'] = user.location
            user_dict['followers'] = user.followers
            user_dict['private_gists'] = user.private_gists
            user_dict['public_gists'] = user.public_gists
            user_dict['name'] = user.name
            user_dict['company'] = user.company
            user_dict['blog_url'] = user.blog
            user_dict['email'] = user.email
            user_dict['id'] = user.id
            user_dict['contributions']={}
            for repo in user.get_watched():
                try:
                    repo_total = 0
                    for _ in repo.get_commits():
                        repo_total = repo_total + 1
                    if repo.get_stats_contributors() is not None:
                        for contributor in repo.get_stats_contributors():
                            if contributor is not None and contributor.author.id == user_dict['id']:
                                user_dict['contributions'][repo.name]={}
                                user_dict['contributions'][repo.name]['contributor_commits']=contributor.total
                                user_dict['contributions'][repo.name]['repo_commits']=repo_total
                                user_dict['contributions'][repo.name]['language']=repo.language
                                user_dict['contributions'][repo.name]['stars']=repo.stargazers_count
                                print user_dict
                                break
                except github.GithubException as e:
                    print e

            f.write(json.dumps(user_dict)+"\n")

if __name__ == '__main__':
    main()

๋‹ค๋ฅธ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋•Œ๋•Œ๋กœ SSL ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

Traceback (most recent call last):
  File "/tmp/collector.py", line 54, in <module>
    main()
  File "/tmp/collector.py", line 36, in main
    for _ in repo.get_commits():
  File "/usr/local/lib/python2.7/dist-packages/github/PaginatedList.py", line 48, in __iter__
    newElements = self._grow()
  File "/usr/local/lib/python2.7/dist-packages/github/PaginatedList.py", line 60, in _grow
    newElements = self._fetchNextPage()
  File "/usr/local/lib/python2.7/dist-packages/github/PaginatedList.py", line 161, in _fetchNextPage
    headers=self.__headers
  File "/usr/local/lib/python2.7/dist-packages/github/Requester.py", line 171, in requestJsonAndCheck
    return self.__check(*self.requestJson(verb, url, parameters, headers, input, cnx))
  File "/usr/local/lib/python2.7/dist-packages/github/Requester.py", line 212, in requestJson
    return self.__requestEncode(cnx, verb, url, parameters, headers, input, encode)
  File "/usr/local/lib/python2.7/dist-packages/github/Requester.py", line 251, in __requestEncode
    status, responseHeaders, output = self.__requestRaw(cnx, verb, url, requestHeaders, encoded_input)
  File "/usr/local/lib/python2.7/dist-packages/github/Requester.py", line 281, in __requestRaw
    output = response.read()
  File "/usr/lib/python2.7/httplib.py", line 557, in read
    s = self._safe_read(self.length)
  File "/usr/lib/python2.7/httplib.py", line 664, in _safe_read
    chunk = self.fp.read(min(amt, MAXAMOUNT))
  File "/usr/lib/python2.7/socket.py", line 380, in read
    data = self._sock.recv(left)
  File "/usr/lib/python2.7/ssl.py", line 341, in recv
    return self.read(buflen)
  File "/usr/lib/python2.7/ssl.py", line 260, in read
    return self._sslobj.read(len)

์•ˆ๋…•,
totalCount๊ฐ€ None์ด๋ผ๋Š” ๊ฒƒ์— ๋Œ€ํ•ด repo.get_pulls().totalCount์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.
๋ฌธ์ œ๋Š” ๋ฐ˜ํ™˜๋œ JSON์— data['total_count']๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
PaginatedList๋Š” ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ __len__ ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

if self.__totalCount:
    return self.__totalCount
else:
   return len(self.__elements)

@pgmillon ๊ณต์ •ํ•˜๊ฒŒ ๋“ค๋ฆฝ๋‹ˆ๋‹ค.
๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ์ž‘์€ PR ์ดˆ์•ˆ์„ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๊ธฐ๊บผ์ด ๋ณ‘ํ•ฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

PaginatedList๋Š” ๊ฒฐ์ฝ” totalCount๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์š”์†Œ์˜ len์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์€ ๋‚ด๊ฐ€ ์ฐพ๊ณ  ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋Š” ํ•ญ๋ชฉ์ด ๋ช‡ ๊ฐœ๋‚˜ ์žˆ๋Š”์ง€ ์•Œ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๋™์˜ํ•˜์ง€๋งŒ AFAIK API๋Š” ๊ทธ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ ํ˜„์žฌ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

opened_pulls = repository.get_pulls()
pulls_count = 0
# Fix no count available on pulls list
for _ in opened_pulls:
    pulls_count += 1

์š”์ :

    from github import Github
    gh = Github()
    gists = gh.get_user('gil9red').get_gists()
    print(gists.totalCount)  # None
    print(len(list(gists)))  # 7

์—ฌ์ „ํžˆ ๊ฐ™์€ ๋ฌธ์ œ:

from github import Github
g = Github()
repos = g.get_repos()
print(repos.totalCount) # None

@gil9red @Tigralt PaginatedList๋ฅผ ๋ฐ˜๋ณตํ•˜์—ฌ ๋ฐ˜ํ™˜๋œ ์ด ํ•ญ๋ชฉ ์ˆ˜๋ฅผ ์–ป์œผ๋ ค๊ณ  ํ•ฉ๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด PaginatedList๋ฅผ ๋ฐ˜๋ณตํ•˜๊ณ  ์นด์šดํŠธ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค์ง€ ์•Š๊ณ ๋Š” ์ด๋ฅผ ์ˆ˜ํ–‰ํ•  ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐ

GitHub๋Š” ํŽ˜์ด์ง€ ๋งค๊น€ ์š”์ฒญ์ด ๋ฐ˜ํ™˜ํ•  ํ•ญ๋ชฉ ์ˆ˜๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ PaginatedList์—๋Š” ๊ธธ์ด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
...
PaginatedList์˜ ๊ธธ์ด๋ฅผ ์‹ค์ œ๋กœ ์ทจํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ๋ช…์‹œ์ ์œผ๋กœ [์›๋ฌธ ๊ทธ๋Œ€๋กœ] ๋ชฉ๋ก์„ ๊ตฌ์„ฑํ•œ ๋‹ค์Œ ํ•ด๋‹น ๊ธธ์ด๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

PaginatedList์˜ ํ•œ ํŽ˜์ด์ง€์— ์žˆ๋Š” ํ•ญ๋ชฉ ์ˆ˜๋ฅผ ์–ป์œผ๋ ค๋Š” ๊ฒฝ์šฐ ์ด PR ์ด ์•„์ง ์—ด๋ ค ์žˆ๊ณ  ๋…ผ์˜ ์ค‘์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋ช‡ ๊ฐ€์ง€ ๊ด€๋ จ ๋ฌธ์ œ ์‚ดํŽด๋ณด๊ธฐ #433 #487 #596

total_count ์ด ์ด์ „ Github API ์‘๋‹ต์—์„œ ์˜จ ๊ฒƒ ๊ฐ™์€๋ฐ์š”? ์šฐ๋ฆฌ๋Š” ์ œ๊ฑฐํ•ด์•ผ TotalCount ์— ์†์„ฑ PaginatedList ๊ตฌํ˜„๊ฐ€ ํŒŒ์†๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ•ญ์ƒ ๋ฐ˜ํ™˜ None . ๋Œ€์‹  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์„œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# To get the total number of available elements in PaginatedList
repos = g.get_user().get_repos()
print(len(list(repos)))  # we can't avoid to iterate through the whole set to get total count

๊ทธ๋ฆฌ๊ณ  ํ˜„์žฌ ์š”์†Œ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด __len__ ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

Github API๋Š” ์ฟผ๋ฆฌ์— ๋Œ€ํ•œ ์ด ํŽ˜์ด์ง€ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฏ€๋กœ per_page=1 ๋ฅผ ์„ค์ •ํ•˜๋ฉด ๋‹จ์ผ ์š”์ฒญ์—์„œ ์ด ํ•ญ๋ชฉ ์ˆ˜๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ฐ˜๋ณต(ํฐ ๊ฒฐ๊ณผ ์ง‘ํ•ฉ์˜ ๊ฒฝ์šฐ)๋ณด๋‹ค ํ›จ์”ฌ ๋” ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@Tommos0 ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค . ์•„๋งˆ๋„ ์ข‹์€ ์ƒ๊ฐ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. Link ํ—ค๋”๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์œ„ํ•ด GET ๋Œ€์‹  HEAD ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” ์ตœ๊ทผ ํ™œ๋™์ด ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž๋™์œผ๋กœ ์˜ค๋ž˜๋œ ๊ฒƒ์œผ๋กœ ํ‘œ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋” ์ด์ƒ์˜ ํ™œ๋™์ด ์—†์œผ๋ฉด ํ์‡„๋ฉ๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ๊ธฐ์—ฌ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

#820์—์„œ ์ˆ˜์ •๋จ

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰