Search code examples
pythonauthenticationvmwarevcloud-director-rest-api

VCloud Director Org user authentication for RestAPI in python


I have VMware setup for testing. I create one user abc/abc123 to access the Org url "http://localhost/cloud/org/MyOrg". I want to access the RestAPI of the VCloud. I tried with RestClient plugin in firefox. Its working fine.

Now I tried with python code.

url = 'https://localhost/api/sessions/'
req = urllib2.Request(url)
base64string = base64.encodestring('%s:%s' % ('abc@MyOrg', 'abc123'))[:-1]
authheader =  "Basic %s" % base64string
req.add_header("Authorization", authheader)
req.add_header("Accept", 'application/*+xml;version=1.5')

f = urllib2.urlopen(req)
data = f.read()
print(data)

This is the code i get from stackoverflow. But for my example its give "urllib2.HTTPError: HTTP Error 403: Forbidden" Error.

I also tried HTTP authentication for the same.


Solution

  • After doing some googling I found the solution from the post https://stackoverflow.com/a/6348729/243031. I change the code for my usability. I am posting the answer because if some one has same error then he will get the answer directly.

    My change code is:

    import urllib2
    import base64
    
    # make a string with the request type in it:
    method = "POST"
    # create a handler. you can specify different handlers here (file uploads etc)
    # but we go for the default
    handler = urllib2.HTTPSHandler()
    # create an openerdirector instance
    opener = urllib2.build_opener(handler)
    # build a request
    url = 'https://localhost/api/sessions'
    request = urllib2.Request(url)
    # add any other information you want
    base64string = base64.encodestring('%s:%s' % ('abc@MyOrg', 'abc123'))[:-1]
    authheader =  "Basic %s" % base64string
    request.add_header("Authorization", authheader)
    request.add_header("Accept",'application/*+xml;version=1.5')
    
    # overload the get method function with a small anonymous function...
    request.get_method = lambda: method
    # try it; don't forget to catch the result
    try:
        connection = opener.open(request)
    except urllib2.HTTPError,e:
        connection = e
    
    # check. Substitute with appropriate HTTP code.
    if connection.code == 200:
        data = connection.read()
        print "Data :", data
    else:
        print "ERRROR", connection.code
    

    Hope this will help some one who want to send POST request without the data.