【问题标题】:Bitbucket API authentication with Python's HTTPBasicAuthHandler使用 Python 的 HTTPBasicAuthHandler 进行 Bitbucket API 身份验证
【发布时间】:2011-05-21 13:59:11
【问题描述】:

我正在尝试使用 bitbucket's API 获取私有存储库中的问题列表。

我已确认 HTTP 基本身份验证适用于 hurl,但我无法在 Python 中进行身份验证。改编自 tutorial 的代码,我编写了以下脚本。

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') 就像一个魅力。

我的代码有什么问题?

【问题讨论】:

    标签: python urllib2 bitbucket bitbucket-api


    【解决方案1】:

    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)
    

    【讨论】:

      【解决方案2】:

      我认为 Python 的 HTTPBasicAuthHandler 没有错误。基本身份验证通常遵循这个过程:

      • 客户端在没有凭据的情况下发出请求;
      • 服务器响应 401 错误;
      • 客户端使用凭据重新发送请求;
      • 服务器响应内容。

      对于 BitBucket,会发生这种情况:

      • 客户端在没有凭据的情况下发出请求;
      • BitBucket 响应公共存储库列表。

      BitBucket 从不发出 401,因此 Python 从不发送凭据。

      看看这个不使用 cookie 的 BitBucket 身份验证示例:

      【讨论】:

        【解决方案3】:

        看看 python-bitbucket,它是 Bitbucket API 的 python 包装器。 original library 仅包括读取访问权限,但 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()
        

        【讨论】:

          【解决方案4】:

          您可以尝试对 HTTPPasswordMgr 进行子类化并覆盖 find_user_password() 方法,以查看您的代码在哪里放弃查找密码。我的猜测是 add_password() 并没有完全符合您的预期。

          【讨论】:

          • 我已经尝试过了,看起来 find_user_password() 没有被调用,但我不明白为什么。无论如何谢谢:)
          猜你喜欢
          • 1970-01-01
          • 2015-02-17
          • 1970-01-01
          • 2023-03-11
          • 2016-08-30
          • 2019-05-11
          • 2018-01-16
          • 1970-01-01
          • 2017-01-21
          相关资源
          最近更新 更多