I am trying to find how i can use basic authentication using urllib2 in python to get the issue KEY The JIRA REST API describes the URI's available
Thanks for the sugestions, i will try it, meanwhile, i just wanted to update this with my own effort: Here is the sample python code i tried:
import urllib2, sys, re, base64
from urlparse import urlparse
theurl = 'http://my.rest-server.com:8080/rest/api/latest/AA-120' # if you want to run this example you'll need to supply a protected page with y
our username and password
username = 'username'
password = 'password' # a very bad password
req = urllib2.Request(theurl)
print req
try:
handle = urllib2.urlopen(req)
print handle
except IOError, e: # here we are assuming we fail
pass
else: # If we don't fail then the page isn't protected
print "This page isn't protected by authentication."
sys.exit(1)
if not hasattr(e, 'code') or e.code != 401: # we got an error - but not a 401 error
print "This page isn't protected by authentication."
print 'But we failed for another reason.'
sys.exit(1)
authline = e.headers.get('www-authenticate', '') # this gets the www-authenticat line from the headers - which has the authentication
scheme and realm in it
if not authline:
print 'A 401 error without an authentication response header - very weird.'
sys.exit(1)
authobj = re.compile(r'''(?:\s*www-authenticate\s*:)?\s*(\w*)\s+realm=['"](\w+)['"]''', re.IGNORECASE) # this regular expression is used to
extract scheme and realm
matchobj = authobj.match(authline)
if not matchobj: # if the authline isn't matched by the regular expression then something is wrong
print 'The authentication line is badly formed.'
sys.exit(1)
scheme = matchobj.group(1)
print scheme
realm = matchobj.group(2)
print realm
if scheme.lower() != 'basic':
print 'This example only works with BASIC authentication.'
sys.exit(1)
base64string = base64.encodestring('%s:%s' % (username, password))[:-1]
authheader = "Basic %s" % base64string
req.add_header("Authorization", authheader)
try:
handle = urllib2.urlopen(req)
except IOError, e: # here we shouldn't fail if the username/password is right
print "It looks like the username or password is wrong."
sys.exit(1)
thepage = handle.read()
server = urlparse(theurl)[1].lower() # server names are case insensitive, so we will convert to lower case
test = server.find(':')
if test != -1: server = server[:test] # remove the :port information if present, we're working on the principle that realm names per serve
r are likely to be unique...
passdict = {(server, realm) : authheader } # now if we get another 401 we can test for an entry in passdict before having to ask the user for a
username/password
print 'Done successfully - information now stored in passdict.'
print 'The webpage is stored in thepage.'
--- and i get the result: This page isn't protected by authentication. But we failed for another reason.
whereas the page is protected by authentication
I tried installing requests, but got error:
sudo easy_install requests
Searching for requests
Reading http://pypi.python.org/simple/requests/
Reading https://github.com/kennethreitz/requests
Reading http://python-requests.org
Best match: requests 0.9.1
Downloading http://pypi.python.org/packages/source/r/requests/requests-0.9.1.tar.gz#md5=8ed4667edb5d57945b74a9137adbb8bd
Processing requests-0.9.1.tar.gz
Running requests-0.9.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-lTQu8K/requests-0.9.1/egg-dist-tmp-M2yQCt
Traceback (most recent call last):
File "/usr/bin/easy_install", line 7, in ?
sys.exit(
File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 1712, in main
with_ei_usage(lambda:
File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 1700, in with_ei_usage
return f()
File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 1716, in <lambda>
distclass=DistributionWithoutHelpCommands, **kw
File "/usr/lib64/python2.4/distutils/core.py", line 149, in setup
dist.run_commands()
File "/usr/lib64/python2.4/distutils/dist.py", line 946, in run_commands
self.run_command(cmd)
File "/usr/lib64/python2.4/distutils/dist.py", line 966, in run_command
cmd_obj.run()
File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 211, in run
self.easy_install(spec, not self.no_deps)
File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 446, in easy_install
return self.install_item(spec, dist.location, tmpdir, deps)
File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 476, in install_item
dists = self.install_eggs(spec, download, tmpdir)
File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 655, in install_eggs
return self.build_and_install(setup_script, setup_base)
File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 930, in build_and_install
self.run_setup(setup_script, setup_base, args)
File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 919, in run_setup
run_setup(setup_script, args)
File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/sandbox.py", line 61, in run_setup
DirectorySandbox(setup_dir).run(
File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/sandbox.py", line 105, in run
return func()
File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/sandbox.py", line 64, in <lambda>
{'__file__':setup_script, '__name__':'__main__'}
File "setup.py", line 6, in ?
File "/tmp/easy_install-lTQu8K/requests-0.9.1/requests/__init__.py", line 26
from . import utils
^
SyntaxError: invalid syntax
I'd recommend considering using the very excellent requests
library which provides a nice abstraction to make urllib2 a bit easier to use.
With requests
you can simply do:
r = requests.get('https://api.github.com', auth=('user', 'pass'))
It supports all of the request methods needed to make REST calls as well (POST, PUT, DELETE, etc...).
You can find more here:
http://pypi.python.org/pypi/requests
If you absolutely MUST use plain old urllib2, here is an example of how it can be done:
import urllib2
theurl = 'http://www.someserver.com/toplevelurl/somepage.htm'
username = 'johnny'
password = 'XXXXXX'
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, theurl, username, password)
# because we have put None at the start it will always
# use this username/password combination for urls
# for which `theurl` is a super-url
authhandler = urllib2.HTTPBasicAuthHandler(passman)
opener = urllib2.build_opener(authhandler)
urllib2.install_opener(opener)
# All calls to urllib2.urlopen will now use our handler
# Make sure not to include the protocol in with the URL, or
# HTTPPasswordMgrWithDefaultRealm will be very confused.
# You must (of course) use it when fetching the page though.
pagehandle = urllib2.urlopen(theurl)
# authentication is now handled automatically for us
More can be found here: http://www.voidspace.org.uk/python/articles/authentication.shtml
Funny, I was working on this yesterday for the JIRA Python CLI. I took the approach of using the REST API to get an authentication cookie and a custom opener. The example below shows using the opener to post data to a page to add a component, but you could replace that with a call to the correct URL for a different REST call.
"""
Demonstration of using Python for a RESTful call to JIRA
Matt Doar
CustomWare
"""
import urllib
import urllib2
import cookielib
jira_serverurl = "http://jira.example.com:8080"
creds = { "username" : "admin", "password" : "admin" }
authurl = jira_serverurl + "/rest/auth/latest/session"
# Get the authentication cookie using the REST API
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
req = urllib2.Request(authurl)
req.add_data('{ "username" : "admin", "password" : "admin" }')
req.add_header("Content-type", "application/json")
req.add_header("Accept", "application/json")
fp = opener.open(req)
fp.close()
add_component_url = jira_serverurl + "/secure/project/AddComponent.jspa?pid=10020&name=ABC4"
print "Using %s" % (add_component_url)
# Have to add data to make urllib2 send a POST
values = {}
data = urllib.urlencode(values)
# Have to tell JIRA to not use a form token
headers = {'X-Atlassian-Token': 'no-check'}
request = urllib2.Request(add_component_url, data, headers=headers)
fp = opener.open(request)
print fp.read()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With