Аутентификация Bitbucket API с помощью Python HTTPBasicAuthHandler

Я пытаюсь получить список проблем в частном репозитории, используя bitbucket API .

Я подтвердил, что базовая аутентификация HTTP работает с hurl, но я не могу пройти аутентификацию в Python. Адаптируя код из этого учебника, я написал следующий сценарий.

import cookielib
import urllib2

class API():
    api_url = 'http://api.bitbucket.org/1.0/'

    def __init__(self, username, password):
        self._opener = self._create_opener(username, password)

    def _create_opener(self, username, password):
        cj = cookielib.LWPCookieJar()
        cookie_handler = urllib2.HTTPCookieProcessor(cj)
        password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
        password_manager.add_password(None, self.api_url, username, password)
        auth_handler = urllib2.HTTPBasicAuthHandler(password_manager)
        opener = urllib2.build_opener(cookie_handler, auth_handler)
        return opener

    def get_issues(self, username, repository):
        query_url = self.api_url + 'repositories/%s/%s/issues/' % (username, repository)
        try:
            handler = self._opener.open(query_url)
        except urllib2.HTTPError, e:
            print e.headers
            raise e
        return handler.read()

api = API(username='my_username', password='XXXXXXXX')

api.get_issues('my_username', 'my_repository') приводит к:

>>> 
Server: nginx/0.7.62
Date: Mon, 19 Apr 2010 16:15:06 GMT
Content-Type: text/plain
Connection: close
Vary: Authorization,Cookie
Content-Length: 9

Traceback (most recent call last):
  File "C:/USERS/personal/bitbucket-burndown/bitbucket-api.py", line 29, in <module>
    print api.get_issues('my_username', 'my_repository')
  File "C:/USERS/personal/bitbucket-burndown/bitbucket-api.py", line 25, in get_issues
    raise e
HTTPError: HTTP Error 401: UNAUTHORIZED

api.get_issues('jespern', 'bitbucket') работает как шарм.

Что не так с моим кодом?


person jbochi    schedule 19.04.2010    source источник


Ответы (4)


Похоже, возникла проблема с HTTPBasicAuthHandler. Это работает:

class API():
    api_url = 'http://api.bitbucket.org/1.0/'

    def __init__(self, username, password, proxy=None):
        encodedstring = base64.encodestring("%s:%s" % (username, password))[:-1]
        self._auth = "Basic %s" % encodedstring
        self._opener = self._create_opener(proxy)

    def _create_opener(self, proxy=None):
        cj = cookielib.LWPCookieJar()
        cookie_handler = urllib2.HTTPCookieProcessor(cj)
        if proxy:
            proxy_handler = urllib2.ProxyHandler(proxy)
            opener = urllib2.build_opener(cookie_handler, proxy_handler)
        else:
            opener = urllib2.build_opener(cookie_handler)
        return opener

    def get_issues(self, username, repository):
        query_url = self.api_url + 'repositories/%s/%s/issues/' % (username, repository)
        try:
            req = urllib2.Request(query_url, None, {"Authorization": self._auth })
            handler = self._opener.open(req)
        except urllib2.HTTPError, e:
            print e.headers
            raise e
        return json.load(handler)
person jbochi    schedule 19.04.2010

Я не думаю, что в Python HTTPBasicAuthHandler есть ошибка. Обычная аутентификация обычно следует этому процессу:

  • Клиент делает запрос без учетных данных;
  • Сервер отвечает ошибкой 401;
  • Клиент повторно отправляет запрос с учетными данными;
  • Сервер отвечает контентом.

В случае с BitBucket это происходит:

  • Клиент делает запрос без учетных данных;
  • BitBucket отвечает списком общедоступных репозиториев.

BitBucket никогда не выдает ошибку 401, поэтому Python никогда не отправляет учетные данные.

Взгляните на этот пример аутентификации с помощью BitBucket без использования файлов cookie:

person Ant    schedule 14.02.2011

Взгляните на python-bitbucket, который представляет собой оболочку Python для API Bitbucket. исходная библиотека включает доступ только для чтения, но ericof включал аутентификацию и некоторый доступ для записи, которые я использовал и использовал здесь: https://bitbucket.org/bkmontgomery/python-bitbucket

Вы можете получить задачи из частного репо следующим образом:

import bitbucket

bb = bitbucket.BitBucket(username='your-username', password='secret')
repo = bb.repository('your-username', 'your-private-repo')
issues = repo.issues()
person Brad Montgomery    schedule 21.05.2011

Вы можете попробовать создать подкласс HTTPPasswordMgr и переопределить метод find_user_password(), чтобы увидеть, где ваш код отказывается от поиска пароля. Я предполагаю, что add_password() делает не совсем то, что вы ожидаете.

person dlamotte    schedule 19.04.2010
comment
Я пробовал это, и похоже, что find_user_password() не вызывался, но я не мог понять, почему. Спасибо, в любом случае :) - person jbochi; 19.04.2010