Skip to content

Instantly share code, notes, and snippets.

@codeofnode
Last active February 26, 2019 09:06
Show Gist options
  • Save codeofnode/4c92e7c53b6b0c28ac33586fd596441d to your computer and use it in GitHub Desktop.
Save codeofnode/4c92e7c53b6b0c28ac33586fd596441d to your computer and use it in GitHub Desktop.
Making http requests with data driven approach in python
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
# 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": 'codeofnode@gmail.com'
},
'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