mirror of
				https://github.com/Telecominfraproject/wlan-lanforge-scripts.git
				synced 2025-10-30 18:27:53 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			417 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			417 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/env python3
 | |
| 
 | |
| # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | |
| # Class holds default settings for json requests                -
 | |
| # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | |
| import logging
 | |
| import sys
 | |
| import os
 | |
| from pprint import pformat, PrettyPrinter
 | |
| import urllib
 | |
| from urllib import request
 | |
| import json
 | |
| 
 | |
| if sys.version_info[0] != 3:
 | |
|     print("This script requires Python 3")
 | |
|     exit()
 | |
| 
 | |
|  
 | |
| sys.path.append(os.path.join(os.path.abspath(__file__ + "../../../../")))
 | |
| 
 | |
| debug_printer = PrettyPrinter(indent=2)
 | |
| 
 | |
| class LFRequest:
 | |
|     Default_Base_URL = "http://localhost:8080"
 | |
|     No_Data = {'No Data':0}
 | |
|     requested_url = ""
 | |
|     post_data = No_Data
 | |
|     default_headers = { 'Accept': 'application/json'}
 | |
|     proxies = None
 | |
|     logger = logging.getLogger(__name__)
 | |
| 
 | |
|     def __init__(self, url=None,
 | |
|                  uri=None,
 | |
|                  proxies_=None,
 | |
|                  debug_=False,
 | |
|                  die_on_error_=False):
 | |
|         self.debug = debug_
 | |
|         self.die_on_error = die_on_error_
 | |
|         self.error_list = []
 | |
| 
 | |
|         # please see this discussion on ProxyHandlers:
 | |
|         # https://docs.python.org/3/library/urllib.request.html#urllib.request.ProxyHandler
 | |
|         # but this makes much more sense:
 | |
|         # https://gist.github.com/aleiphoenix/4159510
 | |
| 
 | |
|         # if debug_:
 | |
|         #     if proxies_ is None:
 | |
|         #         print("LFRequest_init_: no proxies_")
 | |
|         #     else:
 | |
|         #         print("LFRequest: proxies_: ")
 | |
|         #         pprint.pprint(proxies_)
 | |
| 
 | |
|         if (proxies_ is not None) and (len(proxies_) > 0):
 | |
|             if ("http" not in proxies_) and ("https" not in proxies_):
 | |
|                 raise ValueError("Neither http or https set in proxy definitions. Expects proxy={'http':, 'https':, }")
 | |
|             self.proxies = proxies_
 | |
| 
 | |
|         # if debug_:
 | |
|         #     if self.proxies is None:
 | |
|         #         print("LFRequest_init_: no proxies")
 | |
|         #     else:
 | |
|         #         print("LFRequest: proxies: ")
 | |
|         #         pprint.pprint(self.proxies)
 | |
| 
 | |
|         if not url.startswith("http://") and not url.startswith("https://"):
 | |
|             self.logger.warning("No http:// or https:// found, prepending http:// to "+url)
 | |
|             url = "http://" + url
 | |
|         if uri is not None:
 | |
|             if not url.endswith('/') and not uri.startswith('/'):
 | |
|                 url += '/'
 | |
|             self.requested_url = url + uri
 | |
|         else:
 | |
|             self.requested_url = url
 | |
| 
 | |
|         if self.requested_url is None:
 | |
|             raise Exception("Bad LFRequest of url[%s] uri[%s] -> None" % (url, uri))
 | |
| 
 | |
|         if self.requested_url.find('//'):
 | |
|             protopos = self.requested_url.find("://")
 | |
|             self.requested_url = self.requested_url[:protopos + 2] + self.requested_url[protopos + 2:].replace("//", "/")
 | |
| 
 | |
|         # finding '#' prolly indicates a macvlan (eth1#0)
 | |
|         # finding ' ' prolly indicates a field name that should imply %20
 | |
|         if (self.requested_url.find('#') >= 1):
 | |
|             self.requested_url = self.requested_url.replace('#', '%23')
 | |
|         if (self.requested_url.find(' ') >= 1):
 | |
|             self.requested_url = self.requested_url.replace(' ', '+')
 | |
|         self.logger.debug("new LFRequest[%s]" % self.requested_url )
 | |
| 
 | |
|     # request first url on stack
 | |
|     def formPost(self, show_error=True, debug=False, die_on_error_=False):
 | |
|         return self.form_post(show_error=show_error, debug=debug, die_on_error_=die_on_error_)
 | |
| 
 | |
|     def form_post(self, show_error=True, debug=False, die_on_error_=False):
 | |
|         if self.die_on_error:
 | |
|             die_on_error_ = True
 | |
|         if (debug == False) and (self.debug == True):
 | |
|             debug = True
 | |
|         responses = []
 | |
|         urlenc_data = ""
 | |
|         # https://stackoverflow.com/a/59635684/11014343
 | |
|         if (self.proxies is not None) and (len(self.proxies) > 0):
 | |
|             # https://stackoverflow.com/a/59635684/11014343
 | |
|             opener = request.build_opener(request.ProxyHandler(self.proxies))
 | |
|             request.install_opener(opener)
 | |
| 
 | |
| 
 | |
|         self.logger.debug("formPost: url: "+self.requested_url)
 | |
|         if ((self.post_data != None) and (self.post_data is not self.No_Data)):
 | |
|             urlenc_data = urllib.parse.urlencode(self.post_data).encode("utf-8")
 | |
|             self.logger.debug("formPost: data looks like:" + str(urlenc_data))
 | |
|             self.logger.debug("formPost: url: "+self.requested_url)
 | |
|             myrequest = request.Request(url=self.requested_url,
 | |
|                                                 data=urlenc_data,
 | |
|                                                 headers=self.default_headers)
 | |
|         else:
 | |
|             myrequest = request.Request(url=self.requested_url, headers=self.default_headers)
 | |
|             self.logger.error("No data for this formPost?")
 | |
| 
 | |
|         myrequest.headers['Content-type'] = 'application/x-www-form-urlencoded'
 | |
| 
 | |
|         resp = ''
 | |
|         try:
 | |
|             resp = urllib.request.urlopen(myrequest)
 | |
|             responses.append(resp)
 | |
|             return responses[0]
 | |
| 
 | |
|         except urllib.error.HTTPError as error:
 | |
|             print_diagnostics(url_=self.requested_url,
 | |
|                               request_=myrequest,
 | |
|                               responses_=responses,
 | |
|                               error_=error,
 | |
|                               error_list_=self.error_list,
 | |
|                               debug_=debug)
 | |
| 
 | |
|         except urllib.error.URLError as uerror:
 | |
|             print_diagnostics(url_=self.requested_url,
 | |
|                               request_=myrequest,
 | |
|                               responses_=responses,
 | |
|                               error_=uerror,
 | |
|                               error_list_=self.error_list,
 | |
|                               debug_=debug)
 | |
| 
 | |
|         if (die_on_error_ == True) or (self.die_on_error == True):
 | |
|             exit(1)
 | |
|         return None
 | |
| 
 | |
|     def jsonPost(self, show_error=True, debug=False, die_on_error_=False, response_json_list_=None):
 | |
|         return self.json_post(show_error=show_error, debug=debug, die_on_error_=die_on_error_, response_json_list_=response_json_list_)
 | |
| 
 | |
|     def json_post(self, show_error=True, debug=False, die_on_error_=False, response_json_list_=None, method_='POST'):
 | |
|         if (debug == False) and (self.debug == True):
 | |
|             debug = True
 | |
|         if self.die_on_error:
 | |
|             die_on_error_ = True
 | |
|         responses = []
 | |
|         if (self.proxies is not None) and (len(self.proxies) > 0):
 | |
|             opener = urllib.request.build_opener(request.ProxyHandler(self.proxies))
 | |
|             urllib.request.install_opener(opener)
 | |
| 
 | |
|         if ((self.post_data != None) and (self.post_data is not self.No_Data)):
 | |
|             myrequest = request.Request(url=self.requested_url,
 | |
|                                          method=method_,
 | |
|                                          data=json.dumps(self.post_data).encode("utf-8"),
 | |
|                                          headers=self.default_headers)
 | |
|         else:
 | |
|             myrequest = request.Request(url=self.requested_url, headers=self.default_headers)
 | |
|             self.logger.error("No data for this jsonPost?")
 | |
| 
 | |
|         myrequest.headers['Content-type'] = 'application/json'
 | |
| 
 | |
|         # https://stackoverflow.com/a/59635684/11014343
 | |
| 
 | |
|         try:
 | |
|             resp = urllib.request.urlopen(myrequest)
 | |
|             resp_data = resp.read().decode('utf-8')
 | |
|             if (debug and die_on_error_):
 | |
|                 self.logger.debug("----- LFRequest::json_post:128 debug: --------------------------------------------")
 | |
|                 self.logger.debug("URL: <%s>  status: %d "% (self.requested_url, resp.status))
 | |
|                 if resp.status != 200:
 | |
|                     self.logger.debug(pformat(resp.getheaders()))
 | |
|                 self.logger.debug("----- resp_data:128 -------------------------------------------------")
 | |
|                 self.logger.debug(resp_data)
 | |
|                 self.logger.debug("-------------------------------------------------")
 | |
|             responses.append(resp)
 | |
|             if response_json_list_ is not None:
 | |
|                 if type(response_json_list_) is not list:
 | |
|                     raise ValueError("reponse_json_list_ needs to be type list")
 | |
|                 j = json.loads(resp_data)
 | |
|                 if debug:
 | |
|                     self.logger.debug("----- LFRequest::json_post:140 debug: --------------------------------------------")
 | |
|                     self.logger.debug(pformat(j))
 | |
|                     self.logger.debug("-------------------------------------------------")
 | |
|                 response_json_list_.append(j)
 | |
|             return responses[0]
 | |
| 
 | |
|         except urllib.error.HTTPError as error:
 | |
|             print_diagnostics(url_=self.requested_url,
 | |
|                               request_=myrequest,
 | |
|                               responses_=responses,
 | |
|                               error_=error,
 | |
|                               debug_=debug)
 | |
| 
 | |
|         except urllib.error.URLError as uerror:
 | |
|             print_diagnostics(url_=self.requested_url,
 | |
|                               request_=myrequest,
 | |
|                               responses_=responses,
 | |
|                               error_=uerror,
 | |
|                               debug_=debug)
 | |
| 
 | |
|         if die_on_error_ == True:
 | |
|             exit(1)
 | |
|         return None
 | |
| 
 | |
|     def json_put(self, show_error=True, debug=False, die_on_error_=False, response_json_list_=None):
 | |
|        return self.json_post(show_error=show_error,
 | |
|                              debug=debug,
 | |
|                              die_on_error_=die_on_error_,
 | |
|                              response_json_list_=response_json_list_,
 | |
|                              method_='PUT')
 | |
| 
 | |
|     def json_delete(self, show_error=True, debug=False, die_on_error_=False, response_json_list_=None):
 | |
|        return self.get_as_json(method_='DELETE')
 | |
| 
 | |
|     def get(self, method_='GET'):
 | |
|         if self.debug:
 | |
|             self.logger.debug("LFUtils.get: url: "+self.requested_url)
 | |
| 
 | |
|         # https://stackoverflow.com/a/59635684/11014343
 | |
|         if (self.proxies is not None) and (len(self.proxies) > 0):
 | |
|             opener = request.build_opener(request.ProxyHandler(self.proxies))
 | |
|             #opener = urllib.request.build_opener(myrequest.ProxyHandler(self.proxies))
 | |
|             request.install_opener(opener)
 | |
| 
 | |
|         myrequest = request.Request(url=self.requested_url,
 | |
|                                     headers=self.default_headers,
 | |
|                                     method=method_)
 | |
|         myresponses = []
 | |
|         try:
 | |
|             myresponses.append(request.urlopen(myrequest))
 | |
|             return myresponses[0]
 | |
| 
 | |
|         except urllib.error.HTTPError as error:
 | |
|             print_diagnostics(url_=self.requested_url,
 | |
|                               request_=myrequest,
 | |
|                               responses_=myresponses,
 | |
|                               error_=error,
 | |
|                               error_list_=self.error_list,
 | |
|                               debug_=self.debug)
 | |
| 
 | |
|         except urllib.error.URLError as uerror:
 | |
|             print_diagnostics(url_=self.requested_url,
 | |
|                               request_=myrequest,
 | |
|                               responses_=myresponses,
 | |
|                               error_=uerror,
 | |
|                               error_list_=self.error_list,
 | |
|                               debug_=self.debug)
 | |
| 
 | |
|         if self.die_on_error is True:
 | |
|             exit(1)
 | |
|         return None
 | |
| 
 | |
|     def getAsJson(self):
 | |
|         return self.get_as_json()
 | |
| 
 | |
|     def get_as_json(self, method_='GET'):
 | |
|         responses = list()
 | |
|         responses.append(self.get(method_=method_))
 | |
|         if len(responses) < 1:
 | |
|             if self.debug and self.has_errors():
 | |
|                 self.print_errors()
 | |
|             return None
 | |
|         if responses[0] is None:
 | |
|             self.logger.debug("No response from "+self.requested_url)
 | |
|             return None
 | |
|         json_data = json.loads(responses[0].read().decode('utf-8'))
 | |
|         return json_data
 | |
| 
 | |
|     def addPostData(self, data):
 | |
|         self.add_post_data(data=data)
 | |
| 
 | |
|     def add_post_data(self, data):
 | |
|         """
 | |
|         TODO: this is a setter and should be named 'set_post_data'
 | |
|         :param data: dictionary of parameters for post
 | |
|         :return: nothing
 | |
|         """
 | |
|         self.post_data = data
 | |
| 
 | |
|     def has_errors(self):
 | |
|         return (True, False)[len(self.error_list)>0]
 | |
| 
 | |
|     def print_errors(self):
 | |
|         if not self.has_errors:
 | |
|             self.logger.debug("---------- no errors ----------")
 | |
|             return
 | |
|         for err in self.error_list:
 | |
|             self.logger.error("error: %s" % err)
 | |
| 
 | |
| def plain_get(url_=None, debug_=False, die_on_error_=False, proxies_=None):
 | |
|     """
 | |
|     This static method does not respect LFRequest.proxy, it is not set in scope here
 | |
|     :param url_:
 | |
|     :param debug_:
 | |
|     :param die_on_error_:
 | |
|     :return:
 | |
|     """
 | |
|     myrequest = request.Request(url=url_)
 | |
|     myresponses = []
 | |
|     try:
 | |
|         if (proxies_ is not None) and (len(proxies_) > 0):
 | |
|             # https://stackoverflow.com/a/59635684/11014343
 | |
|             opener = myrequest.build_opener(myrequest.ProxyHandler(proxies_))
 | |
|             myrequest.install_opener(opener)
 | |
| 
 | |
|         myresponses.append(request.urlopen(myrequest))
 | |
|         return myresponses[0]
 | |
| 
 | |
|     except urllib.error.HTTPError as error:
 | |
|         print_diagnostics(url_=url_,
 | |
|                           request_=request,
 | |
|                           responses_=myresponses,
 | |
|                           error_=error,
 | |
|                           debug_=debug_)
 | |
| 
 | |
|     except urllib.error.URLError as uerror:
 | |
|         print_diagnostics(url_=url_,
 | |
|                           request_=request,
 | |
|                           responses_=myresponses,
 | |
|                           error_=uerror,
 | |
|                           debug_=debug_)
 | |
| 
 | |
|     if die_on_error_ == True:
 | |
|         exit(1)
 | |
|     return None
 | |
| 
 | |
| 
 | |
| def print_diagnostics(url_=None, request_=None, responses_=None, error_=None, error_list_=None, debug_=False):
 | |
|     logger = logging.getLogger(__name__)
 | |
|     #logger.error("LFRequest::print_diagnostics: error_.__class__: %s"%error_.__class__)
 | |
|     #logger.error(pformat(error_))
 | |
| 
 | |
|     if url_ is None:
 | |
|         logger.warning("WARNING LFRequest::print_diagnostics: url_ is None")
 | |
|     if request_ is None:
 | |
|         logger.warning("WARNING LFRequest::print_diagnostics: request_ is None")
 | |
|     if error_ is None:
 | |
|         logger.warning("WARNING LFRequest::print_diagnostics: error_ is None")
 | |
| 
 | |
|     method = 'NA'
 | |
|     if hasattr(request_, 'method'):
 | |
|         method = request_.method
 | |
|     err_code = 0
 | |
|     err_reason = 'NA'
 | |
|     err_headers = []
 | |
|     err_full_url = url_
 | |
|     if hasattr(error_, 'code'):
 | |
|         err_code = error_.code
 | |
|     if hasattr(error_, 'reason'):
 | |
|         err_reason = error_.reason
 | |
|     if hasattr(error_, 'headers'):
 | |
|         err_headers = error_.headers
 | |
|     if hasattr(error_, 'get_full_url'):
 | |
|         err_full_url = error_.get_full_url()
 | |
|     xerrors = []
 | |
|     if err_code == 404:
 | |
|         xerrors.append("[%s HTTP %s] <%s> : %s" % (method, err_code, err_full_url, err_reason))
 | |
|     else:
 | |
|         if len(err_headers) > 0:
 | |
|             for headername in sorted(err_headers.keys()):
 | |
|                 if headername.startswith("X-Error-"):
 | |
|                     xerrors.append("%s: %s" % (headername, err_headers.get(headername)))
 | |
|         if len(xerrors) > 0:
 | |
|             logger.error(" = = LANforge Error Messages = =")
 | |
|             logger.error(" = = URL: %s" % err_full_url)
 | |
|             for xerr in xerrors:
 | |
|                 logger.error(xerr)
 | |
|                 if (error_list_ is not None) and isinstance(error_list_, list):
 | |
|                     error_list_.append(xerr)
 | |
|             logger.error(" = = = = = = = = = = = = = = = =")
 | |
| 
 | |
|     if error_.__class__ is urllib.error.HTTPError:
 | |
|         logger.debug("----- LFRequest: HTTPError: --------------------------------------------")
 | |
|         logger.debug("%s <%s> HTTP %s: %s" % (method, err_full_url, err_code, err_reason))
 | |
| 
 | |
|         if err_code == 404:
 | |
|             if (error_list_ is not None) and isinstance(error_list_, list):
 | |
|                 error_list_.append("[%s HTTP %s] <%s> : %s" % (method, err_code, err_full_url, err_reason))
 | |
|         else:
 | |
|             logger.debug("  Content-type:[%s] Accept[%s]" % (request_.get_header('Content-type'), request_.get_header('Accept')))
 | |
| 
 | |
|             if hasattr(request_, "data") and (request_.data is not None):
 | |
|                 logger.debug("  Data:")
 | |
|                 logger.debug(debug_printer.pformat(request_.data))
 | |
|             elif debug_:
 | |
|                 logger.debug("    <no request data>")
 | |
| 
 | |
|         if len(err_headers) > 0:
 | |
|             # the HTTPError is of type HTTPMessage a subclass of email.message
 | |
|             logger.debug("  Response Headers: ")
 | |
|             for headername in sorted(err_headers.keys()):
 | |
|                 logger.debug("    %s: %s" % (headername, err_headers.get(headername)))
 | |
| 
 | |
|         if len(responses_) > 0:
 | |
|             logger.debug("----- Response: --------------------------------------------------------")
 | |
|             logger.debug(debug_printer.pformat(responses_[0].reason))
 | |
| 
 | |
|         logger.debug("------------------------------------------------------------------------")
 | |
|         return
 | |
| 
 | |
|     if error_.__class__ is urllib.error.URLError:
 | |
|         logger.error("----- LFRequest: URLError: ---------------------------------------------")
 | |
|         logger.error("%s <%s> HTTP %s: %s" % (method, err_full_url, err_code, err_reason))
 | |
|         logger.error("------------------------------------------------------------------------")
 | |
| 
 | |
| # ~LFRequest
 | 
