Skip to content

Instantly share code, notes, and snippets.

@barkady
Last active May 22, 2024 07:53
Show Gist options
  • Save barkady/26d077fa8556d7d987cb to your computer and use it in GitHub Desktop.
Save barkady/26d077fa8556d7d987cb to your computer and use it in GitHub Desktop.
HP ALM python RESTful client
# -*- coding: utf-8 -*-
__author__ = 'Arkady.Babaev'
import requests
import xml.etree.ElementTree as ET
class ALMUrl:
def __init__(self, ip, port, domain, project):
self.__base = u'http://' + ip + u':' + port + u'/qcbin'
self.__auth = self.__base + u'/authentication-point/authenticate'
self.__logout = self.__base + u'/authentication-point/logout'
self.__work = self.__base + u'/rest/domains/' + domain + u'/projects/' + project
def get_auth(self):
return self.__auth
def get_logout(self):
return self.__logout
def __getattr__(self, *args):
result = self.__work
for arg in args:
result += '/' + arg
return result
class SMFile:
def __init__(self):
self.key = ''
self.filename = ''
self.size = 0
self.body = ''
class ALMSession:
def __init__(self, Logging, login, password):
try:
self.__Logging = Logging
self.__headers = {"Accept":"application/xml",
"Content-Type":"application/xml",
"KeepAlive":"true",
"Cookie": None}#"Authorization":"Basic " + base64.b64encode(login + ':' + password)}
self.__user_pass = (login, password)
except:
self.__Logging.error(u"Exception while creating ALMSession", self.__headers, self.__h)
def parse_xml(self, obj, dict):
almxml = ET.fromstring(obj)
if almxml.__dict__.has_key("TotalResults") and almxml.attrib["TotalResults"] == 0:
return
one_dict = {}
for fields in almxml.findall('.//Fields'):
one_dict.clear()
for field in fields:
curval = field.find("Value")
if curval is not None and curval.text is not None:
one_dict[field.get('Name').decode('utf-8')] = curval.text#field.find("Value").text
if isinstance(one_dict[field.get('Name')], str):
one_dict[field.get('Name').decode('utf-8')] = one_dict[field.get('Name')].decode('utf-8')
dict.append(one_dict.copy())
return
def create_xml(self, entity_type, dictionary):
entity = ET.Element('Entity')
entity.set('Type', entity_type)
fields = ET.SubElement(entity, 'Fields')
for field_name in dictionary:
field = ET.SubElement(fields, 'Field')
field.set('Name', field_name)
value = ET.SubElement(field, 'Value')
if isinstance(dictionary[field_name], list):
dictsum = u''
for line in dictionary[field_name]:
dictsum += (line + u'\r\n')
value.text = dictsum
else:
value.text = dictionary[field_name]
return ET.tostring(entity, encoding="UTF-8", method="xml")
def Open(self, ALMUrl):
#head, context = self.__h.request(ALMUrl.get_auth(), "GET", headers=self.__headers)
r = requests.get(ALMUrl.get_auth(), auth=self.__user_pass)
#if head.status is 200:
if r.status_code is 200:
self.__Logging.info(u"Open ALM session success", u'AUTH URL:', ALMUrl.get_auth(), u'HEADERS:', self.__headers)
self.__headers["Cookie"] = r.headers['set-cookie']
return 0
else:
self.__Logging.error(u"Open ALM session", r.status_code, r.reason, u'AUTH URL:', ALMUrl.get_auth(), u'HEADERS:', self.__headers)
return int(r.status_code)
def Close(self, ALMUrl):
if self.__headers["Cookie"] is not None:
r = requests.get(ALMUrl.get_logout(), headers=self.__headers, auth=self.__user_pass)
if r.status_code is 200:
self.__Logging.info(u"Close ALM session success", u'LOGOUT URL:', ALMUrl.get_logout(), u'HEADERS:', self.__headers)
return 0
else:
self.__Logging.error(u"Close ALM session", r.status_code, r.reason, u'LOGOUT URL:', ALMUrl.get_logout(), u'HEADERS:', self.__headers)
return int(r.status_code)
else:
self.__Logging.error(u"Close ALM session", u"1", u"httplib2.Http was not initialized")
return 1
def GetAttachments(self, ALMUrl, *args):
if self.__headers["Cookie"] is not None:
path = ALMUrl.__getattr__(*args)
r = requests.get(path + u'/attachments', headers=self.__headers, auth=self.__user_pass)
if r.status_code == 200:
files_descr = []
headers = self.__headers.copy()
headers["Accept"] = "application/octet-stream"
self.parse_xml(r.content, files_descr)
result = []
for file in files_descr:
F = SMFile()
F.filename = file[u'name']
F.size = file[u'file-size']
F.key = file[u'id']
r = requests.get(path + u'/attachments/' + F.filename, headers=headers, auth=self.__user_pass)
if r.status_code == 200:
F.body = r.content
result.append(F)
else:
self.__Logging.info(u"[ALMSession] Get attach file problem", u"URL:", path + u'/attachments/' + F.filename, u"HEADERS:", headers, F.filename)
return int(r.status_code), None
self.__Logging.info(u"[ALMSession] Get attach success", u"URL:", ALMUrl.__getattr__(*args), u"HEADERS:", self.__headers)
return 0, result
elif r.status_code == 500:
try:
if isinstance(r.text, unicode):
exceptionxml = ET.fromstring(r.text.encode('utf8','ignore'))
else:
exceptionxml = ET.fromstring(r.text)
self.__Logging.error(u"[ALMSession] Get ALM function with errors", exceptionxml[0].text, exceptionxml[1].text, u"PATH:", ALMUrl.__getattr__(*args), u"HEADERS:", self.__headers)
except ET.ParseError:
self.__Logging.error(u"[ALMSession] Get ALM function with errors, returned message is not XML", u"PATH:", ALMUrl.__getattr__(*args), u"HEADERS:", self.__headers, ET.ParseError.message)
return int(r.status_code), None
else:
self.__Logging.error(u"[ALMSession] Get ALM function with errors", r.status_code, r.reason, u"PATH:", ALMUrl.__getattr__(*args), u"HEADERS:", self.__headers)
return int(r.status_code), None
else:
self.__Logging.error(u"[ALMSession] Get ALM function with errors", u"1", u"httplib2.Http not initialized")
return 1, None
def Get(self, ALMUrl, *args):
if self.__headers["Cookie"] is not None:
r = requests.get(ALMUrl.__getattr__(*args), headers=self.__headers, auth=self.__user_pass)
if r.status_code == 200:
self.__Logging.info(u"[ALMSession] Get success", u"URL:", ALMUrl.__getattr__(*args), u"HEADERS:", self.__headers)
res = []
self.parse_xml(r.content, res)
return 0, res
elif r.status_code == 500:
try:
if isinstance(r.text, unicode):
exceptionxml = ET.fromstring(r.text.encode('utf8','ignore'))
else:
exceptionxml = ET.fromstring(r.text)
self.__Logging.error(u"[ALMSession] Get ALM function with errors", exceptionxml[0].text, exceptionxml[1].text, u"PATH:", ALMUrl.__getattr__(*args), u"HEADERS:", self.__headers)
except ET.ParseError:
self.__Logging.error(u"[ALMSession] Get ALM function with errors, returned message is not XML", u"PATH:", ALMUrl.__getattr__(*args), u"HEADERS:", self.__headers, ET.ParseError.message)
return int(r.status_code), None
else:
self.__Logging.error(u"[ALMSession] Get ALM function with errors", r.status_code, r.reason, u"PATH:", ALMUrl.__getattr__(*args), u"HEADERS:", self.__headers)
return int(r.status_code), None
else:
self.__Logging.error(u"[ALMSession] Get ALM function with errors", u"1", u"httplib2.Http not initialized")
return 1, None
def Update(self, ALMUrl, data, *args):
if self.__headers["Cookie"] is not None:
r = requests.put(ALMUrl.__getattr__(*args),
headers=self.__headers,
data=data,
auth=self.__user_pass)
if r.status_code == 200:
self.__Logging.info(u"[ALMSession] Update success", u"URL:", ALMUrl.__getattr__(*args))
return 0
elif r.status_code == 500:
if isinstance(r.text, unicode):
exceptionxml = ET.fromstring(r.text.encode('utf8','ignore'))
else:
exceptionxml = ET.fromstring(r.text)
self.__Logging.error(u"[ALMSession] Update ALM function with errors", exceptionxml[0].text, exceptionxml[1].text, u"PATH:", ALMUrl.__getattr__(*args), u"DATA:", data, u"HEADERS:", self.__headers)
return int(r.status_code)
else:
self.__Logging.error(u"[ALMSession] Update ALM function with errors", r.status_code, r.reason, u"PATH:", ALMUrl.__getattr__(*args), u"DATA:", data, u"HEADERS:", self.__headers)
return int(r.status_code)
else:
self.__Logging.error(u"[ALMSession] Update ALM function with errors", u"1", u"httplib2.Http not initialized")
return 1
def AddFile(self, ALMUrl, files, *args):
if self.__headers["Cookie"] is not None:
fileToSend = {}
for file in files:
fileToSend[file.filename] = file.body
locheaders = self.__headers.copy()
#locheaders[u'Content-Type'] = u'application/octet-stream'
r = requests.post(ALMUrl.__getattr__(*args),
headers=locheaders,
files=fileToSend,
auth=self.__user_pass)
if r.status_code == 201:
self.__Logging.info(u"[ALMSession] Create success", u"URL:", ALMUrl.__getattr__(*args))
return 0, r.headers._store['location'][1].split('/')[-1]
elif r.status_code == 500:
if isinstance(r.text, unicode):
exceptionxml = ET.fromstring(r.text.encode('utf8','ignore'))
else:
exceptionxml = ET.fromstring(r.text)
self.__Logging.error(u"[ALMSession] Create ALM function with errors", exceptionxml[0].text, exceptionxml[1].text, u"PATH:", ALMUrl.__getattr__(*args), u"DATA:", data, u"HEADERS:", self.__headers)
return int(r.status_code), ""
else:
self.__Logging.error(u"[ALMSession] Create ALM function with errors", r.status_code, r.reason, u"PATH:", ALMUrl.__getattr__(*args), u"HEADERS:", self.__headers)
return int(r.status_status), ""
else:
self.__Logging.error(u"[ALMSession] Create ALM function with errors", u"1", u"httplib2.Http not initialized")
return 1, ""
def Create(self, ALMUrl, data, *args):
if self.__headers["Cookie"] is not None:
r = requests.post(ALMUrl.__getattr__(*args),
headers=self.__headers,
data=data,
auth=self.__user_pass)
if r.status_code == 201:
self.__Logging.info(u"[ALMSession] Create success", u"URL:", ALMUrl.__getattr__(*args))
return 0, r.headers._store['location'][1].split('/')[-1]
elif r.status_code == 500:
if isinstance(r.text, unicode):
exceptionxml = ET.fromstring(r.text.encode('utf8','ignore'))
else:
exceptionxml = ET.fromstring(r.text)
self.__Logging.error(u"[ALMSession] Create ALM function with errors", exceptionxml[0].text, exceptionxml[1].text, u"PATH:", ALMUrl.__getattr__(*args), u"DATA:", data, u"HEADERS:", self.__headers)
return int(r.status_code), ""
else:
self.__Logging.error(u"[ALMSession] Create ALM function with errors", r.status_code, r.reason, u"PATH:", ALMUrl.__getattr__(*args), u"HEADERS:", self.__headers)
return int(r.status_status), ""
else:
self.__Logging.error(u"[ALMSession] Create ALM function with errors", u"1", u"httplib2.Http not initialized")
return 1, ""
def Delete(self, ALMUrl, *args):
if self.__headers["Cookie"] is not None:
r = requests.delete(ALMUrl.__getattr__(*args),
headers=self.__headers,
auth=self.__user_pass)
if r.status_code == 200:
self.__Logging.info(u"[ALMSession]Delete success", u"URL:", ALMUrl.__getattr__(*args))
#r.store
return 0
elif r.status_code == 500:
if isinstance(r.text, unicode):
exceptionxml = ET.fromstring(r.text.encode('utf8','ignore'))
else:
exceptionxml = ET.fromstring(r.text)
self.__Logging.error(u"[ALMSession] Delete ALM function with errors", exceptionxml[0].text, exceptionxml[1].text, u"PATH:", ALMUrl.__getattr__(*args), u"HEADERS:", self.__headers)
return int(r.status_code)
else:
self.__Logging.error(u"[ALMSession] Delete ALM function with errors", r.status_code, r.reason, u"PATH:", ALMUrl.__getattr__(*args), u"HEADERS:", self.__headers)
return int(r.status_status)
else:
self.__Logging.error(u"[ALMSession] Delete ALM function with errors", u"1", u"httplib2.Http not initialized")
return 1
@AnveshGoud
Copy link

AnveshGoud commented Jan 24, 2017

Hi,

This is good work you have done.

I am facing an issue, if you could help. Authentication is happening successfully but unable to get xml response later on and requests are throwing 401 errors.

Do you happen to know the cause?

Thanks.

@tlnarayana
Copy link

tlnarayana commented Jan 25, 2017

Hi Avinesh,

I'm new to the usage of restAPI

could you help me - how do you survived - successful connection ?
I'm not near to that stop ! :(

My requirement is
1.Connect HP ALM
2.Navigate to test instance in test lab
3.update the status of test instance's test case --> PASS or FAIL

Line#213 : giving syntax error - Undefined variable data

This what is shown in my pyDev !

@jufei
Copy link

jufei commented Feb 10, 2017

I have connected to the server successfully. Now I need to get the case list under a test set, how should I do this?

Thanks in advance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment