Bitbucket autenticazione API con Python HTTPBasicAuthHandler
-
28-09-2019 - |
Domanda
Sto cercando di ottenere l'elenco dei problemi su un repository privato utilizzando di bitbucket API .
mi hanno confermato che HTTP di base di autenticazione funziona con Hurl , ma sono in grado di autenticare in Python. Adattare il codice da questa esercitazione , ho scritto il seguente script.
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')
Risultati api.get_issues('my_username', 'my_repository')
in:
>>>
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')
funziona come un fascino.
Cosa c'è di sbagliato con il mio codice?
Soluzione
Sembra che ci sia un problema con HTTPBasicAuthHandler . Questo funziona:
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)
Altri suggerimenti
Non credo ci sia un errore di di Python HTTPBasicAuthHandler. L'autenticazione di base di solito segue questo processo:
- marche client richiesta senza credenziali;
- risponde Server con 401 errori;
- rinvii richiesta del client con le credenziali;
- risponde Server con contenuti.
Nel caso di BitBucket, questo accade:
- marche client richiesta senza credenziali;
- risponde bitbucket con la lista dei repository pubblici.
BitBucket mai emette il 401, in modo da Python non invia le credenziali.
Date un'occhiata a questo esempio per l'autenticazione con BitBucket senza utilizzare i cookie:
Date un'occhiata a python-bitbucket , che è un wrapper Python per API Bitbucket. Il libreria originale include solo l'accesso in lettura, ma ericof autenticazione incluso e un po 'l'accesso in scrittura, che ho tirato in e sviluppata qui: https://bitbucket.org/bkmontgomery/python-bitbucket
Si potrebbe recuperare Problemi da un repo privato nel seguente modo:
import bitbucket
bb = bitbucket.BitBucket(username='your-username', password='secret')
repo = bb.repository('your-username', 'your-private-repo')
issues = repo.issues()
Si potrebbe provare sub-classing HTTPPasswordMgr e l'override del metodo find_user_password () per vedere dove il codice è rinunciare a trovare la password. La mia ipotesi è che add_password () non sta facendo esattamente quello che ci si aspetterebbe.