Last active
February 26, 2019 09:06
-
-
Save codeofnode/4c92e7c53b6b0c28ac33586fd596441d to your computer and use it in GitHub Desktop.
Making http requests with data driven approach in python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import urllib2, json | |
reqopener = urllib2.build_opener(urllib2.HTTPHandler) | |
""" | |
To resolve template string from variable dictionary | |
Input: | |
@strvar: string on which replacement to be made | |
@varsdict: the dictionary that will be used to resolve the template object | |
Returns: | |
The resolved value, or the as it is string if not resolved by variable dictionary | |
""" | |
def templateString(strvar, varsdict): | |
if not isinstance(strvar, basestring) or not strvar.startswith('{{') or not strvar.endswith('}}'): | |
return strvar | |
ky = strvar[2:-2] | |
kysps = ky.split('.') | |
curr = varsdict | |
for ky in kysps: | |
if ky in curr: | |
curr = curr[ky] | |
else: | |
return strvar | |
return curr | |
""" | |
To resolve template object from variable dictionary | |
Input: | |
@obj: object on which replacement to be made | |
@varsdict: the dictionary that will be used to resolve the template object | |
Returns: | |
The resolved object value, replaced on nested values too | |
""" | |
def templateObject(obj, varsdict): | |
if not isinstance(obj, dict) or not isinstance(varsdict, dict): | |
return | |
for ky, vl in obj.iteritems(): | |
if isinstance(vl, dict): | |
templateObject(vl, varsdict) | |
else: | |
obj[ky] = templateString(vl, varsdict) | |
""" | |
This will fire a set of requests, put the assertions | |
Input: | |
@requests: list of request to be fired | |
@varsdict: the dictionary that will be used to resolve the variables in payload and headers. Also it will save the extractors | |
Returns: | |
@allSucceeded : True if all requests succeeded else False | |
@rollbacks: list of all rollbacks required, in case of failure | |
""" | |
def fireRequests(requests, varsdict): | |
rollbacks = [] | |
try: | |
for req in requests: | |
if not req: | |
continue | |
if 'callfunction' in req: | |
if callable(req['callfunction']): | |
req['callfunction'](varsdict, *(req['params']) if 'params' in req else None) | |
continue; | |
for fl in ['data', 'headers']: | |
if fl in req and req[fl] is not None: | |
templateObject(req[fl], varsdict) | |
else: | |
req[fl] = {} | |
req['url'] = "/".join(map(lambda x: templateString(x, varsdict), req['url'].split('/'))) | |
if 'method' not in req or req['method'] == 'GET': | |
reqMade = urllib2.Request(req['url'], headers=req['headers']) | |
else: | |
req['method'] = templateString(req['method'], varsdict) | |
if req['method'] == 'NONE': | |
continue | |
reqMade = urllib2.Request(req['url'], data=json.dumps(req['data']), headers=req['headers']) | |
reqMade.add_header('Content-Type', 'application/json') | |
reqMade.get_method = lambda: req['method'] | |
requestMade = reqopener.open(reqMade) | |
content = requestMade.read() | |
if content.startswith('{') or content.startswith('['): | |
resp_auth = json.loads(content) | |
else: | |
resp_auth = {} | |
print ('NON JSON RESPONSE : '+content) | |
if 'assertions' in req: | |
for ky, vl in req['assertions'].iteritems(): | |
if ky not in resp_auth or vl != resp_auth[ky]: | |
print ('RESPONSE : '+content) | |
return False, rollbacks | |
if 'rollback' in req: | |
rollbacks.append(req['rollback']) | |
if 'extractors' in req: | |
for ky, vl in req['extractors'].iteritems(): | |
if vl in resp_auth: | |
varsdict[ky] = resp_auth[vl] | |
return True, rollbacks | |
except Exception as e: | |
print ('ERROR RECIEVED WHILE REQUEST : '+str(e)) | |
return False, rollbacks |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# how to use above | |
vardict = { | |
'apiUrl' : 'https://api.someurl.com', | |
'xAuthToken': 'some-token' | |
} | |
requests = [{ | |
'url': '{{apiUrl}}/users', | |
'method': 'POST', | |
'headers': { | |
'x-auth-token': '{{xAuthToken}}' | |
}, | |
'data': { | |
"username": 'codeofnode' | |
}, | |
'assertions': { | |
'statusCode': 201 | |
}, | |
'extractors': { | |
'user' : 'user | |
} | |
},{ | |
'url': '{{apiUrl}}/users/{{user.id}}', | |
'method': 'PUT', | |
'headers': { | |
'x-auth-token': '{{xAuthToken}}' | |
}, | |
'data': { | |
"email": '[email protected]' | |
}, | |
'assertions': { | |
'statusCode': 200 | |
}, | |
'rollback': { | |
'url': '{{apiUrl}}/users/{{user.id}}', | |
'method': 'DELETE', | |
'headers': { | |
'x-auth-token': '{{xAuthToken}}' | |
}, | |
'assertions': { | |
'statusCode': 200 | |
} | |
} | |
}] | |
rollbacks = fireRequests(requests, vardict) | |
if rollbacks != True: | |
moreRollbacks = fireRequests(rollbacks, vardict) | |
if moreRollbacks != True: | |
print "Operation failed with rollbacks " + str(rollbacks) | |
return False | |
else: | |
return False | |
else: | |
return True |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment