Pygithub: ์ตœ๊ทผ ์ž„์˜์˜ 401 ์ž˜๋ชป๋œ ์ž๊ฒฉ ์ฆ๋ช… ์˜ˆ์™ธ

์— ๋งŒ๋“  2013๋…„ 03์›” 21์ผ  ยท  4์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: PyGithub/PyGithub

์•ˆ๋…•ํ•˜์„ธ์š”,

PyGithub๋Š” ๋ฒ„๋ ค์ง„ ํ”„๋กœ์ ํŠธ์˜ ํฌํฌ ์ธ https://github.com/Borkason/google-code-issues-migrator ์˜ ์ผ๋ถ€์ด๋ฉฐ ์ตœ๊ทผ์—๋Š” ํ•ด๋‹น ์Šคํฌ๋ฆฝํŠธ์—์„œ ์ž„์˜์˜ 401 ์ž˜๋ชป๋œ ์ž๊ฒฉ ์ฆ๋ช… ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ˆ์™ธ๋Š” ๊ณผ๊ฑฐ์— ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— PyGithub๊ฐ€ ์ž๊ฒฉ ์ฆ๋ช…์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ๊ด€๋ จ์ด์žˆ์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. Github๊ฐ€ ์ง€๋‚œ 1 ~ 2 ๊ฐœ์›” ๋™์•ˆ ๋ญ”๊ฐ€๋ฅผ ๋ณ€๊ฒฝํ–ˆ์„๊นŒ์š”?

์˜ˆ์™ธ์˜ ๋ชจ์–‘์—์„œ ์•„์ง ํŒจํ„ด์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ฌด์ž‘์œ„๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ์ œ๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค
__main__ ์—์„œ ํ•œ ๋ฒˆ ์ธ์ฆํ•ฉ๋‹ˆ๋‹ค : https://github.com/Borkason/google-code-issues-migrator/blob/master/migrateissues.py#L493.
๊ทธ๋Ÿฐ ๋‹ค์Œ ๋ชจ๋“  ๋ฌธ์ œ๋ฅผ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ๋Š” ๋ชจ๋“  ๋ฌธ์ œ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  Google ์ฝ”๋“œ API๋กœ ๋ช‡ ๊ฐ€์ง€ ์ž‘์—…์„ ์ˆ˜ํ–‰ ํ•œ ๋‹ค์Œ ์ฃผ์„์„ ํฌํ•จํ•˜์—ฌ github์—์„œ ์ƒˆ๋กœ์šด ๋ฌธ์ œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„ ๋ฌธ์ œ๋ฅผ ๋งŒ๋“œ๋Š” ๋™์•ˆ ์˜ˆ์™ธ๋ฅผ๋ฐ›์Šต๋‹ˆ๋‹ค. ํ•ญ์ƒ ์ž„์˜์˜ ์ง€์ ์—์„œ (๋•Œ๋กœ๋Š” 2 ๊ฐœ์˜ ๋ฌธ์ œ๋ฅผ ์ถ”๊ฐ€ ํ•œ ํ›„, ๋•Œ๋กœ๋Š” 100 ๊ฐœ์˜ ๋ฌธ์ œ๋ฅผ ์ถ”๊ฐ€ ํ•œ ํ›„ ...

_ ์–ด๋–ค ์‹ ์œผ๋กœ๋“  ๋„์›€์„ ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค ._

์ด๊ฒƒ์€ ์˜ˆ์™ธ์ž…๋‹ˆ๋‹ค

Traceback (most recent call last):
  File "migrateissues.py", line 529, in <module>
    process_gcode_issues(existing_issues)
  File "migrateissues.py", line 332, in process_gcode_issues
    add_comments_to_issue(github_issue, gid)
  File "migrateissues.py", line 236, in add_comments_to_issue
    existing_comments = [ comment.body for comment in github_issue.get_comments() ]
  File "/usr/local/lib/python2.7/dist-packages/PyGithub-1.12.2-py2.7.egg/github/PaginatedList.py", line 35, in __iter__
    newElements = self.__grow()
  File "/usr/local/lib/python2.7/dist-packages/PyGithub-1.12.2-py2.7.egg/github/PaginatedList.py", line 47, in __grow
    newElements = self._fetchNextPage()
  File "/usr/local/lib/python2.7/dist-packages/PyGithub-1.12.2-py2.7.egg/github/PaginatedList.py", line 104, in _fetchNextPage
    headers, data = self.__requester.requestJsonAndCheck("GET", self.__nextUrl, self.__nextParams, None)
  File "/usr/local/lib/python2.7/dist-packages/PyGithub-1.12.2-py2.7.egg/github/Requester.py", line 84, in requestJsonAndCheck
    return self.__check(*self.requestJson(verb, url, parameters, input))
  File "/usr/local/lib/python2.7/dist-packages/PyGithub-1.12.2-py2.7.egg/github/Requester.py", line 92, in __check
    raise GithubException.GithubException(status, output)
github.GithubException.GithubException: 401 {u'message': u'Bad credentials'}
question

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

์•ˆ๋…•ํ•˜์„ธ์š”!

์ง€๋‚œ ๋ฉฐ์น  ๋™์•ˆ์ด ๋ฌธ์ œ๋„ ๊ฒฝํ—˜ํ–ˆ์Šต๋‹ˆ๋‹ค. GIthub ์ธก์˜ ๋ฒ„๊ทธ ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. PyGithub์™€ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์…ธ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์žฌํ˜„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (๋กœ๊ทธ์ธ ๋ฐ ์•”ํ˜ธ๋ฅผ ์ธ์ˆ˜๋กœ ์‚ฌ์šฉํ•˜์—ฌ ํ˜ธ์ถœ).

#!/bin/sh

USER=$1
PASSWORD=$2

CONTINUE=1

while [ $CONTINUE == "1" ]
do
    OUTPUT=$(curl --include https://$USER:[email protected]/user 2>&1)

    if echo "$OUTPUT" | grep "200 OK" >/dev/null
    then
        echo OK
    else
        date
        echo "$OUTPUT"
        CONTINUE=0
    fi
done

ํŠน์ • ์ˆ˜์˜ "OK"๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  PyGithub์—์„œ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ๋กœ ์ด์–ด์ง€๋Š” ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋กœ ๋๋‚ฉ๋‹ˆ๋‹ค.

[...]
OK
OK
OK
OK
Thu Mar 21 20:35:50 RST 2013
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    35  100    35    0     0     57      0 --:--:-- --:--:-- --:--:--    70HTTP/1.1 401 Unauthorized
Server: GitHub.com
Date: Thu, 21 Mar 2013 19:35:53 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Status: 401 Unauthorized
X-GitHub-Media-Type: github.beta
Content-Length: 35

{
  "message": "Bad credentials"
}

Github์— ์ง์ ‘ ๋ฒ„๊ทธ๋ฅผ ์ œ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์–ด์ œ๋Š” ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ๊ณ  ์˜ค๋Š˜๋„ ์™„์ „ํžˆ ๋„์ฒญ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

PaginatedList.py์—์„œ Github ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋น ๋ฅด๊ณ  ๋”๋Ÿฌ์šด ํ•ดํ‚น์„ํ–ˆ์Šต๋‹ˆ๋‹ค.

def _fetchNextPage(self):
        myWorkaround = True
        while myWorkaround:
                try:
                        headers, data = self.__requester.requestJsonAndCheck("GET", self.__nextUrl, self.__nextParams, None)
                        myWorkaround = False
                except:
                        pass

        [โ€ฆ]

์˜ค๋Š˜ ๋‚˜๋Š” ๋˜ํ•œ API์— ๋ช‡ ๊ฐ€์ง€ (ํŽ˜์ด์ง€๊ฐ€ ๋งค๊ฒจ์ง€์ง€ ์•Š์€) ์š”์ฒญ ๋งŒ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์Šคํฌ๋ฆฝํŠธ ๋ฌธ์ œ๋ฅผ ๊ฒฝํ—˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜์—๊ฒŒ ์ ˆ๋Œ€์ ์œผ๋กœ ์ค‘์š”ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ GitHub์— ์ง์ ‘ ์—ฐ๋ฝ ํ•  ์‹œ๊ฐ„์ด ์—†์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” ํŽ˜์ด์ง€ ๋งค๊น€๋ณด๋‹ค ๋” ์ผ๋ฐ˜์ ์ด๋ฏ€๋กœ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์ •๋ง๋กœ ํ•„์š”ํ•œ ๊ฒฝ์šฐ Requester.py ์—์„œ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๋ผ์ธ 143 ๊ต์ฒด

status, responseHeaders, output = self.__requestRaw(verb, url, requestHeaders, encoded_input)

๋น„์Šทํ•œ ๊ฒƒ์œผ๋กœ

status = 401
retries = 5
while retries > 0 and status == 401:
    status, responseHeaders, output = self.__requestRaw(verb, url, requestHeaders, encoded_input)
    retries -= 1

(๋‚˜๋Š” ์ „ํ˜€ ํ…Œ์ŠคํŠธํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค)

์Šค ๋‹ˆํŽซ์„ ์ œ๊ณตํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. : +1 :
Github์— ์—ฐ๋ฝํ–ˆ์ง€๋งŒ ํ•ด๋‹น ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ ํ•  ์ˆ˜์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์žˆ์œผ๋ฏ€๋กœ ๋” ์ด์ƒ ์‹œ๊ฐ„์„ ํˆฌ์žํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. :)

๊ฑด๋ฐฐ.

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