if len(sys.argv) != 3: print "You must provide a URL and JSON object" sys.exit(1) url_re = re.compile( r'^https?://' # http:// or https:// r'(?:(?:[A-Z0-9-]+\.)+[A-Z]{2,6}|' #domain... r'localhost|' #localhost... r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip r'(?::\d+)?' # optional port r'(?:/?|/\S+)$', re.IGNORECASE) # check we have a valid url if not url_re.match(sys.argv[1]): print "You must provide a valid URL" sys.exit(1) # print a message as it may take time for the responce to return print "Connecting to %s" % sys.argv[1] # make the request try: conn = Connection(sys.argv[1]) # otherwise we should just print the response response = conn.request_put("/", body=sys.argv[2]) except socket.error: print "We couldn't connect to %s" % sys.argv[1] sys.exit(1) print "Response was %s" % response['headers'].status
#!/usr/bin/python import csv import simplejson as json from restful_lib import Connection #conn = Connection("http://mc933.lab.ic.unicamp.br:8010") conn = Connection("http://mc933.lab.ic.unicamp.br:8010/getBusesPositions") #response = conn.request_get("/getPosition") response = conn.request_get("") buses = json.loads(response["body"]) for i in buses: response = conn.request_get(str(i)) obj = json.loads(response["body"]) writer = csv.writer(open('points.csv', 'ab')) #, delimiter=' ', quotechar='|', quoting=csv.QUOTE_MINIMAL #writer.writerow(['Horario', 'Latitude', 'Longitude']) writer.writerow([datetime.strftime(datetime.now(), "%d/%m/%Y %H:%M:%S"), str(lat), str(lon)]) return "Point (" + str(lat) + ',' + str(lon) + ") saved at " + datetime.strftime(datetime.now(), "%d/%m/%Y %H:%M:%S") #print response["body"] + "\n" #coordenada = json.loads(response["body"]) conn.request_put("/sidewinder", {'color': 'blue'}, headers={'content-type':'application/json', 'accept':'application/json'})
#!/usr/bin/python from restful_lib import Connection conn = Connection("http://localhost:8888") response = conn.request_get("/getNearestBusStops?lat=-22.8177;lon=-47.0683") print response['body'] conn.request_put("/sidewinder", {'color': 'blue'}, headers={'content-type':'application/json', 'accept':'application/json'})
class SensorBase: def __init__(self, host, email, password): """ Set up a connection with the sensorbase host """ self.host = host self.email = email self.password = password self.connection = Connection(self.host, self.email, self.password) def get_sensordata(self,user=None): """ Deprecated! Written during development to get acquainted with Hackystat's REST API. Might become handy if sensorbase.py becomes a python lib to interact with hackystat. Refactoring needed? """ if user == None: user = self.email response = self.connection.request_get("/sensordata"+user) xml_string = response[u'body'] tree = ET.XML(xml_string) ET.dump(tree) def put_sensordata(self, datatype="", tool="", resource="", properties=""): """ Used to put up new sensordata on the hackystat server. Creates and XML element tree according to the xml schema (hardcoded). Will probably need some refactoring later on. """ time = self.get_timestamp() # build a tree structure e_sensordata = ET.Element("SensorData") e_timestamp = ET.SubElement(e_sensordata, "Timestamp") e_timestamp.text = time e_runtime = ET.SubElement(e_sensordata, "Runtime") e_runtime.text = time e_tool = ET.SubElement(e_sensordata, "Tool") e_tool.text = tool e_datatype = ET.SubElement(e_sensordata, "SensorDataType") e_datatype.text = datatype e_resource = ET.SubElement(e_sensordata, "Resource") e_resource.text = resource e_owner = ET.SubElement(e_sensordata, "Owner") e_owner.text = self.email e_properties = ET.SubElement(e_sensordata, "Properties") for property_key in properties.keys(): e_property = ET.SubElement(e_properties, "Property") e_key = ET.SubElement(e_property, "Key") e_key.text = property_key e_value = ET.SubElement(e_property, "Value") e_value.text = properties[property_key] uri = "/sensordata/[email protected]/"+time response = self.connection.request_put(uri, None, ET.tostring(e_sensordata)) print response def get_timestamp(self,hour=0,minute=0): time_current = datetime.now() time_current = time_current + timedelta(hours=hour,minutes=minute) #Time format for both oldcurrent timestamp time_format = "%Y-%m-%dT%H:%M:%S.000" timestamp = time.strftime(time_format, time_current.timetuple()) return timestamp def get_sensor_datatype(self,data): """ Deprecated! Written during development to get acquainted with Hackystat's REST API. Might become handy if sensorbase.py becomes a python lib to interact with hackystat. Refactoring needed? """ name = data.attrib['Name'] response = self.connection.request_get("/sensordatatypes/"+name) xml_string = response[u'body'] tree = ET.XML(xml_string) return response[u'body'] def get_projectdata(self,user=None,project=None,args=None): """ Get project data from hackystat server. If no user is defined it uses the email login used to initiate the connection, if no project is defined it uses 'Default'. Arguments in a dictionary are just forwarded. Returns the body of the response. Would it be better for this function to be a generator of responses? Might be tricky to implement given the structure of hackystat repsonses. """ if user == None: user = self.email if project == None: project = "Default" response = self.connection.request_get("/projects/"+\ user+"/"+project+\ "/sensordata",args) return response[u'body']
class RedmineRESTAPIWrapper(object): def __init__(self, settings): self.api_key = settings.redmine_api_key self.conn = Connection(settings.redmine_url) def request_put(self, path, payload): return self.conn.request_put(path, args= [ ('key', self.api_key) ], body=json.dumps(payload), headers={'content-type':'application/json', 'accept':'application/json'}) def request_post(self, path, payload): return self.conn.request_post(path, args= [ ('key', self.api_key) ], body=json.dumps(payload), headers={'content-type':'application/json', 'accept':'application/json'}) def request_get(self, path, payload): return self.conn.request_get(path, args= [ ('key', self.api_key) ] + payload, headers={'content-type':'application/json', 'accept':'application/json'}) def put_items_with_payload(self, url, payload_name, items, payload): if not isinstance(items, set): items = set([items]) for i in items: resp = self.request_put("/{}/".format(url)+str(i)+".json", { payload_name: payload}) status = resp[u'headers']['status'] print 'Item {} '.format(url), i, ', http status code: ', status if int(status) != 200: print resp def put_issues_with_payload(self, issues, payload): return self.put_items_with_payload("issues", "issue", issues, payload) def put_versions_with_payload(self, versions, payload): return self.put_items_with_payload("versions", "version", versions, payload) def post_time_entries_with_payload(self, payload): resp = self.request_post("/time_entries.json", {'time_entry': payload}) status = resp[u'headers']['status'] print 'Issue ', payload['issue_id'], ', http status code: ', status def get_items_as_json(self, endpoint, payload): resp = self.request_get("/"+endpoint+".json", payload) status = resp[u'headers']['status'] return resp[u'body'] def get_time_entries(self, payload): return self.get_items_as_json('time_entries', payload) def get_projects(self, payload): return self.get_items_as_json('projects', payload) def set_projects_parent(self, projects, parent_id): return self.put_items_with_payload("projects", "project", projects, { 'parent_id': parent_id}) def add_issues_to_milestone(self, issues, version_id, milestone_name): self.put_issues_with_payload(issues, {'notes': 'Issue added to milestone: '+milestone_name, 'fixed_version_id': version_id}) def add_issues_on_sprint(self, issues, sprint_id, sprint_name): self.put_issues_with_payload(issues, {'notes': 'Issue added to sprint "'+sprint_name+'" from REST API', 'easy_sprint_id': sprint_id}) def set_issues_status(self, issues, status_id): self.put_issues_with_payload(issues, {'status_id': status_id}) def set_issues_status_and_assigned(self, issues, status_id, assigned_id): self.put_issues_with_payload(issues, {'status_id': status_id, 'assigned_to_id': assigned_id}) def set_issues_assigned(self, issues, assigned_id): self.put_issues_with_payload(issues, {'assigned_to_id': assigned_id}) def set_parent_issue(self, issues, parent_id): self.put_issues_with_payload(issues,{'parent_issue_id': parent_id}) def add_notes_on_issues(self, issues, notes): self.put_issues_with_payload(issues,{'notes': notes}) def add_update_on_commit(self, issue, repo_name, branch_name, commit_hash, commit_msg): notes = "Repo <b>%s</b> branch <b>%s</b> commit <b>%s</b>: %s" % (repo_name, branch_name, commit_hash, commit_msg) return self.add_notes_on_issues(set([issue]), notes) def add_update_on_commit_from_line(self, line, repo_name, branch_name): (commit_hash, commit_msg) =line.split(' ',1) match = re.search("\#(\d+)", commit_msg) if match: issue = match.group(1) resp =self.add_update_on_commit(issue,repo_name, branch_name, commit_hash, commit_msg) def add_issues_to_milestone_1(self, issues): self.add_issues_to_milestone(issues, 61, "Milestone 1") def close_issues(self, issues): self.set_issues_status(issues, settings.statuses['closed']) def get_items_as_json_full(self, endpoint, params = None, process_cb = None): (offset, limit, read, total) = (0, 25, 0, 65535) if params is None: params = [] result = [] while read<total: _params = params + [('limit', limit), ('offset', offset)] resp = json.loads(self.get_items_as_json(endpoint, _params)) # add_to_list(resp["time_entries"], label) result += resp[endpoint] if process_cb is not None: process_cb(resp[endpoint]) total = resp["total_count"] read += limit if (limit+offset < total) else total - offset offset += limit return result
#This is a little example of how to make a PUT request (see http://microformats.org/wiki/rest/urls ) #To a API written with tastypie (https://github.com/toastdriven/django-tastypie ) # import the standard JSON parser import json # import the REST library (from http://code.google.com/p/python-rest-client/) from restful_lib import Connection #site url base_url = "http://IP/api/v1" conn = Connection(base_url) #get the global config dict globalconfig = conn.request_get('/globalconfig/') globalconfig = json.loads(globalconfig["body"]) globalconfig = globalconfig["objects"][0] #set the args globalconfig["sfftrim"] = True #make the put REST request to update the resource result = conn.request_put('/globalconfig/1/', body=json.dumps(globalconfig), headers={'content-type': 'application/json'})
class Odl: """Connect to ODL and do REST transactions.""" def __init__(self, base_url): """Connect to ODL.""" self.conn = Connection(base_url, username=v.username, password=v.password) self.log = logging.getLogger('ODL') def clean_up(self): """Clean up ODL configuration.""" params = {'node_id': v.rt1_node_id, 'name': v.auto_tunnel_name} self.post_remove_lsp(params) def read_file(self, filename, params=None): """Return the file contents after substituting the params if any.""" f = open(filename, 'r') contents = f.read() f.close() if params: contents = Template(contents) contents = contents.substitute(params) return contents def get(self, path): """Request REST GET transaction with timeout.""" return timeout(self, self.request, ('GET', path, {})) def post(self, path, body): """Request REST POST transaction with timeout.""" return timeout(self, self.request, ('POST', path, body)) def put(self, path, body): """Request REST PUT transaction with timeout.""" return timeout(self, self.request, ('PUT', path, body)) def request(self, operation, path, body): """Request REST transactions.""" self.log.info("%s : %s", operation, path) if body != {}: self.log.debug("Body : %s", json.dumps(json.loads(body), indent=2)) headers = {'content-type':'application/json', 'accept':'application/json'} if operation == 'GET': response = self.conn.request_get(path, args={}, headers=headers) elif operation == 'POST': response = self.conn.request_post(path, args={}, body=body, headers=headers) elif operation == 'PUT': response = self.conn.request_put(path, args={}, body=body, headers=headers) status = int(response['headers']['status']) self.log.info("Response : %s %s", status, httplib.responses[status]) response_body = json.loads(response['body']) self.log.debug("Response Body : %s\n", json.dumps(response_body, indent=2)) return status, response_body def get_pcep_topology(self, params=None): """Return the content of PCEP topology response.""" return self.get("/operational/network-topology:network-topology/topology/pcep-topology") def post_add_lsp(self, params=None): """Add LSP and return the content of the response.""" self.node_id = params['node_id'] # Required for auto undo if params.has_key('sid'): body = self.read_file(v.add_lsp_sr_file, params) elif params.has_key('sid2'): body = self.read_file(v.add_lsp_sr2_file, params) elif params.has_key('sid3'): body = self.read_file(v.add_lsp_sr3_file, params) else: body = self.read_file(v.add_lsp_file, params) return self.post("/operations/network-topology-pcep:add-lsp", body) def post_update_lsp(self, params=None): """Update LSP and return the content of the response.""" if params.has_key('sid'): body = self.read_file(v.update_lsp_sr_file, params) elif params.has_key('sid2'): body = self.read_file(v.update_lsp_sr2_file, params) elif params.has_key('sid3'): body = self.read_file(v.update_lsp_sr3_file, params) else: body = self.read_file(v.update_lsp_file, params) return self.post("/operations/network-topology-pcep:update-lsp", body) def post_remove_lsp(self, params=None): """Remove LSP and return the content of the response.""" if params is None: # Auto undo params = {} move_attr_to_params(self, params, 'node_id') if params.has_key("node_id"): body = self.read_file(v.remove_lsp_file, params) return self.post("/operations/network-topology-pcep:remove-lsp", body) def post_add_label(self, params=None): """Add label and return the content of the response.""" if params.has_key('in_label') and params.has_key('out_label'): body = self.read_file(v.add_label_dwnld_in_out_file, params) elif params.has_key('in_label'): body = self.read_file(v.add_label_dwnld_in_file, params) elif params.has_key('out_label'): body = self.read_file(v.add_label_dwnld_out_file, params) elif params.has_key('node_label'): body = self.read_file(v.add_label_map_node_file, params) elif params.has_key('adj_label'): body = self.read_file(v.add_label_map_adj_file, params) else: body = self.read_file(v.add_label_db_sync_end_file, params) return self.post("/operations/network-topology-pcep:add-label", body) def post_remove_label(self, params=None): """Remove label and return the content of the response.""" body = self.read_file(v.remove_label_file, params) return self.post("/operations/network-topology-pcep:remove-label", body)
class RestClientEngine(object): __metaclass__ = Singleton def __init__(self, conn=None): if not conn: self.conn = Connection(GENERAL_PARAMETERS['base_url'], username=GENERAL_PARAMETERS['username'], password=GENERAL_PARAMETERS['password']) else: self.conn = conn def executeRequest(self, identifier, body=None, query_parameter=None, **kwargs): """ Execute a Http request using pre configured configurations. :param identifier Identifier of the configuration block of the request. :param body Body content of the request. Default None. :param query_parameter Query parameters of URL. apis/apiServ?param1=value1&... Default None. :param kwargs You can include in it pathVariables and extra headers. :return Dictionary with the body response and headers that contains status code too. :raises NotFoundException if a parameter is not present in config or in method call. """ rel_url = self.buildUrl(identifier, kwargs) headers = self.buildHeaders(identifier, kwargs) if identifier in REQUESTS: if REQUESTS[identifier]['method'] in ('get', 'post', 'put', 'delete'): if REQUESTS[identifier]['method'] == 'get': return self.conn.request_get(rel_url, headers=headers, args=query_parameter) elif REQUESTS[identifier]['method'] == 'post': return self.conn.request_post(rel_url, headers=headers, body=body) elif REQUESTS[identifier]['method'] == 'put': return self.conn.request_put(rel_url, headers=headers, body=body) elif REQUESTS[identifier]['method'] == 'delete': return self.conn.request_delete(rel_url, headers=headers) else: raise NotFoundException('method not found') else: raise NotFoundException('method not found') def buildHeaders(self, identifier, kwargs): result = {} if 'headers' in GENERAL_PARAMETERS: for key, value in GENERAL_PARAMETERS['headers'].items(): result[key] = value if identifier in REQUESTS: if 'headers' in REQUESTS[identifier]: for key, value in REQUESTS[identifier]['headers'].items(): result[key] = value else: raise NotFoundException('Request identifier not found exception.') if 'headers' in kwargs: for key, value in kwargs['headers'].items(): result[key] = value if GENERAL_PARAMETERS['username'] and GENERAL_PARAMETERS['password']: result['Authorization'] = ''.join([ 'Basic ', base64.b64encode(':'.join([ GENERAL_PARAMETERS['username'], GENERAL_PARAMETERS['password'] ])) ]) return result def buildUrl(self, identifier, kwargs): if identifier in REQUESTS: relative_url = REQUESTS[identifier]['relative_url'] else: raise NotFoundException('Request identifier not found exception.') parameters = self.getParameterFromConfigFile(relative_url) replaced_relative_url = self.replaceParameters(relative_url, parameters, kwargs) return replaced_relative_url def getParameterFromConfigFile(self, relative_url): return re.findall('{(?P<parameter>[a-zA-Z%0-9_-]+)}', relative_url) def replaceParameters(self, relative_url, parameters, kwargs): result = relative_url for parameter in parameters: if parameter in kwargs: result = result.replace(''.join(['{', parameter, '}']), kwargs[parameter], 1) else: raise NotFoundException(''.join( ['Parameter ', parameter, ' not found for build the url'])) return result
class AdflyApiExample(): #FROM EXAMPLE ## BASE_HOST = 'https://api.adf.ly' ## # TODO: Replace this with your secret key. ## SECRET_KEY = '4c8fa05a-d826-4c06-86e4-59b86bf4868c' ## # TODO: Replace this with your public key. ## PUBLIC_KEY = '2ba3f6ce601d043c177eb2a83eb34f5f' ## # TODO: Replace this with your user id. ## USER_ID = 2 ## AUTH_TYPE = dict(basic=1, hmac=2) BASE_HOST = 'https://api.adf.ly' SECRET_KEY = 'YOUR SECRET KEY' PUBLIC_KEY = 'YOUR PUBLIC KEY' USER_ID = 'YOUR USER ID' AUTH_TYPE = dict(basic=1, hmac=2) def __init__(self): # In this example we use rest client provided by # http://code.google.com/p/python-rest-client/ # Of course you are free to use any other client. self._connection = Connection(self.BASE_HOST) def get_groups(self, page=1): response = self._connection.request_get('/v1/urlGroups', args=self._get_params( dict(_page=page), self.AUTH_TYPE['hmac'])) return json.loads(response['body']) def expand(self, urls, hashes=[]): params = dict() if type(urls) == list: for i, url in enumerate(urls): params['url[%d]' % i] = url elif type(urls) == str: params['url'] = urls if type(hashes) == list: for i, hashval in enumerate(hashes): params['hash[%d]' % i] = hashval elif type(hashes) == str: params['hash'] = hashes response = self._connection.request_get('/v1/expand', args=self._get_params( params, self.AUTH_TYPE['basic'])) return json.loads(response['body']) def shorten(self, urls, domain=None, advert_type=None, group_id=None): params = dict() if domain: params['domain'] = domain if advert_type: params['advert_type'] = advert_type if group_id: params['group_id'] = group_id if type(urls) == list: for i, url in enumerate(urls): params['url[%d]' % i] = url elif type(urls) == str: params['url'] = urls response = self._connection.request_post('/v1/shorten', args=self._get_params( params, self.AUTH_TYPE['basic'])) return json.loads(response['body']) def get_urls(self, page=1, search_str=None): response = self._connection.request_get('/v1/urls', args=self._get_params( dict(_page=page, q=search_str), self.AUTH_TYPE['hmac'])) return json.loads(response['body']) def update_url(self, url_id, **kwargs): params = dict() allowed_kwargs = [ 'url', 'advert_type', 'title', 'group_id', 'fb_description', 'fb_image' ] for k, v in kwargs.items(): if k in allowed_kwargs: params[k] = v response = self._connection.request_put('/v1/urls/%d' % url_id, args=self._get_params( params, self.AUTH_TYPE['hmac'])) return json.loads(response['body']) def delete_url(self, url_id): response = self._connection.request_delete('/v1/urls/%d' % url_id, args=self._get_params( dict(), self.AUTH_TYPE['hmac'])) return json.loads(response['body']) def _get_params(self, params={}, auth_type=None): """Populates request parameters with required parameters, such as _user_id, _api_key, etc. """ auth_type = auth_type or self.AUTH_TYPE['basic'] params['_user_id'] = self.USER_ID params['_api_key'] = self.PUBLIC_KEY if self.AUTH_TYPE['basic'] == auth_type: pass elif self.AUTH_TYPE['hmac'] == auth_type: # Get current unix timestamp (UTC time). params['_timestamp'] = int(time.time()) params['_hash'] = self._do_hmac(params) else: raise RuntimeError return params def _do_hmac(self, params): if type(params) != dict: raise RuntimeError # Get parameter names. keys = params.keys() # Sort them using byte ordering. # So 'param[10]' comes before 'param[2]'. keys.sort() queryParts = [] # Url encode query string. The encoding should be performed # per RFC 1738 (http://www.faqs.org/rfcs/rfc1738) # which implies that spaces are encoded as plus (+) signs. for key in keys: quoted_key = urllib.quote_plus(str(key)) if params[key] is None: params[key] = '' quoted_value = urllib.quote_plus(str(params[key])) queryParts.append('%s=%s' % (quoted_key, quoted_value)) return hmac.new(self.SECRET_KEY, '&'.join(queryParts), hashlib.sha256).hexdigest()