def render_xml(self, resp): self.set_header("Content-Type", mediatypes.APPLICATION_XML) if hasattr(resp, '__module__'): resp = convert2XML(resp) if isinstance(resp, xml.dom.minidom.Document): self.write(resp.toxml()) self.finish()
def _exe(self, method): """ Executes the python function for the Rest Service """ request_path = self.request.path path = request_path.split('/') services_and_params = list(filter(lambda x: x != '', path)) content_type = None if 'Content-Type' in self.request.headers.keys(): content_type = self.request.headers['Content-Type'] # Get all funcion names configured in the class RestHandler functions = list( filter( lambda op: hasattr(getattr(self, op), '_service_name') == True and inspect.ismethod(getattr(self, op)) == True, dir(self))) # Get all http methods configured in the class RestHandler http_methods = list( map(lambda op: getattr(getattr(self, op), '_method'), functions)) if method not in http_methods: raise tornado.web.HTTPError( 405, 'The service not have %s verb' % method) if path[1] not in list( op._path.split('/')[1] for op in list(map(lambda o: getattr(self, o), functions))): raise tornado.web.HTTPError(404, '404 Not Found {}'.format(path[1])) for operation in list(map(lambda op: getattr(self, op), functions)): service_name = getattr(operation, '_service_name') service_params = getattr(operation, '_service_params') # If the _types is not specified, assumes str types for the params params_types = getattr(operation, "_types") or [str] * len(service_params) params_types = params_types + [str] * (len(service_params) - len(params_types)) produces = getattr(operation, '_produces') consumes = getattr(operation, '_consumes') services_from_request = list( filter(lambda x: x in path, service_name)) query_params = getattr(operation, '_query_params') manual_response = getattr(operation, '_manual_response') catch_fire = getattr(operation, '_catch_fire') if operation._method == self.request.method and service_name == services_from_request and len( service_params) + len(service_name) == len( services_and_params): try: params_values = self._find_params_value_of_url( service_name, request_path ) + self._find_params_value_of_arguments(operation) p_values = self._convert_params_values( params_values, params_types) if consumes == None and content_type != None: consumes = content_type if consumes == mediatypes.APPLICATION_XML: param_obj = None body = self.request.body if sys.version_info > (3, ): body = str(body, 'utf-8') if len(body) > 0 and params_types[0] in [str]: param_obj = xml.dom.minidom.parseString(body) elif len(body) > 0: param_obj = convertXML2OBJ( params_types[0], xml.dom.minidom.parseString( body).documentElement) if param_obj != None: p_values.append(param_obj) elif consumes == mediatypes.APPLICATION_JSON: param_obj = None body = self.request.body if sys.version_info > (3, ): body = str(body, 'utf-8') if len(body) > 0 and params_types[0] in [dict, str]: param_obj = json.loads(body) elif len(body) > 0: param_obj = convertJSON2OBJ( params_types[0], json.loads(body)) if param_obj != None: p_values.append(param_obj) elif consumes == mediatypes.TEXT_PLAIN: body = self.request.body if len(body) >= 1: if sys.version_info > (3, ): body = str(body, 'utf-8') if isinstance(body, str): param_obj = body else: param_obj = convertJSON2OBJ( params_types[0], json.loads(body)) p_values.append(param_obj) response = operation(*p_values) if response == None: return if produces != None: self.set_header('Content-Type', produces) if manual_response: return if (produces == mediatypes.APPLICATION_JSON or produces == None) and hasattr(response, '__module__'): response = convert2JSON(response) elif produces == mediatypes.APPLICATION_XML and hasattr( response, '__module__') and not isinstance( response, xml.dom.minidom.Document): response = convert2XML(response) if produces == None and (isinstance(response, dict) or isinstance(response, str)): self.write(response) self.finish() elif produces == None and isinstance(response, list): self.write(json.dumps(response)) self.finish() elif produces == mediatypes.TEXT_PLAIN and isinstance( response, str): self.write(response) self.finish() elif produces == mediatypes.APPLICATION_JSON and isinstance( response, dict): self.write(response) self.finish() elif produces == mediatypes.APPLICATION_JSON and isinstance( response, list): self.write(json.dumps(response)) self.finish() elif produces in [ mediatypes.APPLICATION_XML, mediatypes.TEXT_XML ] and isinstance(response, xml.dom.minidom.Document): self.write(response.toxml()) self.finish() else: self.gen_http_error( 500, 'Internal Server Error : response is not %s document' % produces) if catch_fire == True: raise PyRestfulException( 'Internal Server Error : response is not %s document' % produces) except Exception as detail: self.gen_http_error(500, 'Internal Server Error : %s' % detail) if catch_fire == True: raise PyRestfulException(detail)
def _exe(self, method): """ Executes the python function for the Rest Service """ request_path = self.request.path path = request_path.split('/') services_and_params = list(filter(lambda x: x!='',path)) content_type = None if 'Content-Type' in self.request.headers.keys(): content_type = self.request.headers['Content-Type'] # Get all funcion names configured in the class RestHandler functions = list(filter(lambda op: hasattr(getattr(self,op),'_service_name') == True and inspect.ismethod(getattr(self,op)) == True, dir(self))) # Get all http methods configured in the class RestHandler http_methods = list(map(lambda op: getattr(getattr(self,op),'_method'), functions)) if method not in http_methods: raise tornado.web.HTTPError(405,'The service not have %s verb'%method) for operation in list(map(lambda op: getattr(self,op), functions)): service_name = getattr(operation,"_service_name") service_params = getattr(operation,"_service_params") # If the _types is not specified, assumes str types for the params params_types = getattr(operation,"_types") or [str]*len(service_params) params_types = params_types + [str]*(len(service_params)-len(params_types)) produces = getattr(operation,"_produces") consumes = getattr(operation,"_consumes") services_from_request = list(filter(lambda x: x in path,service_name)) query_params = getattr(operation,"_query_params") if operation._method == self.request.method and service_name == services_from_request and len(service_params) + len(service_name) == len(services_and_params): try: params_values = self._find_params_value_of_url(service_name,request_path) + self._find_params_value_of_arguments(operation) p_values = self._convert_params_values(params_values, params_types) if consumes == None and produces == None: consumes = content_type produces = content_type if consumes == mediatypes.APPLICATION_XML: param_obj = convertXML2OBJ(params_types[0],xml.dom.minidom.parseString(self.request.body).documentElement) p_values.append(param_obj) elif consumes == mediatypes.APPLICATION_JSON: body = self.request.body if sys.version_info > (3,): body = str(self.request.body,'utf-8') param_obj = convertJSON2OBJ(params_types[0],json.loads(body)) p_values.append(param_obj) response = operation(*p_values) if response == None: return self.set_header("Content-Type",produces) if produces == mediatypes.APPLICATION_JSON and hasattr(response,'__module__'): response = convert2JSON(response) elif produces == mediatypes.APPLICATION_XML and hasattr(response,'__module__'): response = convert2XML(response) if produces == mediatypes.APPLICATION_JSON and isinstance(response,dict): self.write(response) self.finish() elif produces == mediatypes.APPLICATION_JSON and isinstance(response,list): self.write(json.dumps(response)) self.finish() elif produces in [mediatypes.APPLICATION_XML,mediatypes.TEXT_XML] and isinstance(response,xml.dom.minidom.Document): self.write(response.toxml()) self.finish() else: self.gen_http_error(500,"Internal Server Error : response is not %s document"%produces) except Exception as detail: self.gen_http_error(500,"Internal Server Error : %s"%detail) # 修改的地方 调用RequestHandler的处理请求异常的方法 self._handle_request_exception(detail)
def _exe(self, method): ''' Executes the python function for the Rest Service ''' request_path = self.request.path path = request_path.split('/') services_and_params = [p for p in path if p != ''] content_type = None if 'Content-Type' in self.request.headers.keys(): content_type = self.request.headers['Content-Type'] # Get all funcion names configured in the class RestHandler functions = [ op for op in dir(self) if hasattr(getattr(self, op), '_service_name') and inspect.ismethod(getattr(self, op)) ] # Get all http methods configured in the class RestHandler http_methods = [ getattr(getattr(self, op), '_method') for op in functions ] if method not in http_methods: raise tornado.web.HTTPError( 405, 'The service not have %s verb' % method) for operation in [getattr(self, op) for op in functions]: service_name = getattr(operation, '_service_name') service_params = getattr(operation, '_service_params') # If the _types is not specified, assumes str types for the params params_types = getattr(operation, '_types') or [str] * len(service_params) params_types = params_types + [str] * (len(service_params) - len(params_types)) produces = getattr(operation, '_produces') consumes = getattr(operation, '_consumes') services_from_request = [s for s in service_name if s in path] query_params = getattr(operation, '_query_params') if operation._method == self.request.method and service_name == services_from_request and len( service_params) + len(service_name) == len( services_and_params): try: url_params = self._find_params_value_of_url( service_name, request_path) arg_params = self._find_params_value_of_arguments( operation) params_values = url_params + arg_params p_values = self._convert_params_values( params_values, params_types) if consumes is None and produces is None: consumes = content_type produces = content_type if consumes == mediatypes.APPLICATION_XML: param_obj = convertXML2OBJ( params_types[0], xml.dom.minidom.parseString( self.request.body).documentElement) p_values.append(param_obj) elif consumes == mediatypes.APPLICATION_JSON: body = self.request.body if sys.version_info > (3, ): body = str(self.request.body, 'utf-8') param_obj = convertJSON2OBJ(params_types[0], json.loads(body)) p_values.append(param_obj) response = operation(*p_values) if response is None: return self.set_header('Content-Type', produces) if produces == mediatypes.APPLICATION_JSON and hasattr( response, '__module__'): response = convert2JSON(response) elif produces == mediatypes.APPLICATION_XML and hasattr( response, '__module__'): response = convert2XML(response) if produces == mediatypes.APPLICATION_JSON and isinstance( response, dict): self.write(response) self.finish() elif produces == mediatypes.APPLICATION_JSON and isinstance( response, list): self.write(json.dumps(response)) self.finish() elif produces in [ mediatypes.APPLICATION_XML, mediatypes.TEXT_XML ] and isinstance(response, xml.dom.minidom.Document): self.write(response.toxml()) self.finish() else: self.gen_http_error( 500, 'Internal Server Error : response is not %s document' % produces) except Exception as detail: self.gen_http_error(500, 'Internal Server Error : %s' % detail)
def _exe(self, method): """ Executes the python function for the Rest Service """ request_path = self.request.path path = request_path.split('/') services_and_params = filter(lambda x: x!='',path) # Get all funcion names configured in the class RestHandler functions = filter(lambda op: hasattr(getattr(self,op),'_service_name') == True and inspect.ismethod(getattr(self,op)) == True, dir(self)) # Get all http methods configured in the class RestHandler http_methods = map(lambda op: getattr(getattr(self,op),'_method'), functions) if method not in http_methods: raise tornado.web.HTTPError(405,'The service not have %s verb'%method) for operation in map(lambda op: getattr(self,op), functions): service_name = getattr(operation,"_service_name") service_params = getattr(operation,"_service_params") # If the _types is not specified, assumes str types for the params params_types = getattr(operation,"_types") or [str]*len(service_params) params_types = map(lambda x,y : y if x is None else x, params_types, [str]*len(service_params)) produces = getattr(operation,"_produces") consumes = getattr(operation,"_consumes") services_from_request = filter(lambda x: x in path,service_name) query_params = getattr(operation,"_query_params") if operation._method == self.request.method and service_name == services_from_request and len(service_params) + len(service_name) == len(services_and_params): try: params_values = self._find_params_value_of_url(service_name,request_path) + self._find_params_value_of_arguments(operation) p_values = self._convert_params_values(params_values, params_types) if consumes == mediatypes.APPLICATION_XML: param_obj = convertXML2OBJ(params_types[0],xml.dom.minidom.parseString(self.request.body).documentElement) p_values.append(param_obj) elif consumes == mediatypes.APPLICATION_JSON: param_obj = convertJSON2OBJ(params_types[0],json.loads(self.request.body)) p_values.append(param_obj) response = operation(*p_values) if response == None: return self.set_header("Content-Type",produces) if produces == mediatypes.APPLICATION_JSON and hasattr(response,'__module__'): response = convert2JSON(response) elif produces == mediatypes.APPLICATION_XML and hasattr(response,'__module__'): response = convert2XML(response) if produces == mediatypes.APPLICATION_JSON and isinstance(response,dict): self.write(response) self.finish() elif produces == mediatypes.APPLICATION_JSON and isinstance(response,list): self.write(json.dumps(response)) self.finish() elif produces in [mediatypes.APPLICATION_XML,mediatypes.TEXT_XML] and isinstance(response,xml.dom.minidom.Document): self.write(response.toxml()) self.finish() else: self.gen_http_error(500,"Internal Server Error : response is not %s document"%produces) except Exception as detail: self.gen_http_error(500,"Internal Server Error : %s"%detail)
def _exe(self, method): """ 执行函数的核心模块 :param method: :return: """ # 处理URL,获取URL中的资源名和参数 request_path = self.request.path path = request_path.split("/") services_and_params = list(filter(lambda x: x != "", path)) # 设置HTTP文本类型 content_type = None if "Content-Type" in self.request.headers.keys(): content_type = self.request.headers["Content-Type"] # 充分利用Python特性的一行代码,获取资源Handler中所有被config装饰过的函数名 functions = list( # 将结果转成列表 filter( # 高阶函数, lambda op: hasattr(getattr(self, op), "_service_name") and inspect.ismethod(getattr(self, op)), dir(self))) # 获取资源类支持的HTTP方法:GET/POST/DELETE/PUT等 http_methods = list( map(lambda op: getattr(getattr(self, op), "_method"), functions)) if method not in http_methods: raise tornado.web.HTTPError( 405, "The service not have %s verb" % method) # list(map(lambda op: getattr(self, op), functions)) 获取资源类方法的每个operation进行 for operation in list(map(lambda op: getattr(self, op), functions)): # 循环遍历资源类中每个方法的OP属性,是否满足当前的请求,如果满足进行处理 service_name = getattr(operation, "_service_name") service_params = getattr(operation, "_service_params") # If the _types is not specified, assumes str types for the params params_types = getattr(operation, "_types") func_params = getattr(operation, "_func_params") params_types += [str] * (len(func_params) - len(params_types)) produces = getattr(operation, "_produces") # 输出格式 consumes = getattr(operation, "_consumes") # 输入格式 services_from_request = list( filter(lambda x: x in path, service_name)) manual_response = getattr(operation, "_manual_response") catch_fire = getattr(operation, "_catch_fire") op_method = getattr(operation, "_method") if op_method == self.request.method and service_name == services_from_request and len( service_params) + len(service_name) == len( services_and_params): try: # 获取HTTP请求参数,包括?之前的资源参数和?之后的参数,注意顺序 params_values = self._find_params_value_of_url(service_name, request_path) + \ self._find_params_value_of_arguments(operation) p_values = self._convert_params_values( params_values, params_types) # 如果HTTP请求的request和response没预设参数,则使用HTTP请求头中的content-type参数 # 接写来就是对请求的body进行处理 # 如下代码是原来作者写的,感觉比较冗余,一般一个服务的数据传输格式是统一的。 # 而具体request中的body数据如何处理,是业务而定,这块使用的时候可以随时修改 # if not (consumes or produces): # consumes = content_type # produces = content_type # if consumes == mediatypes.APPLICATION_XML: # if params_types[0] in [str]: # param_obj = xml.dom.minidom.parseString(self.request.body) # else: # param_obj = convertXML2OBJ(params_types[0], # xml.dom.minidom.parseString(self.request.body).documentElement) # p_values.append(param_obj) # elif consumes == mediatypes.APPLICATION_JSON: # body = self.request.body # if sys.version_info > (3,): # body = str(self.request.body, "utf-8") # if params_types[0] in [dict, str]: # param_obj = json.loads(body) # else: # param_obj = convertJSON2OBJ(params_types[0], json.loads(body)) # p_values.append(param_obj) # 真正的业务逻辑函数 response = operation(*p_values) # 对输出的结果进行处理 if not response: return if produces: self.set_header("Content-Type", produces) if manual_response: return if produces == mediatypes.APPLICATION_JSON and hasattr( response, "__module__"): response = convert2JSON(response) elif produces == mediatypes.APPLICATION_XML and hasattr( response, "__module__") and not isinstance( response, xml.dom.minidom.Document): response = convert2XML(response) if produces == mediatypes.APPLICATION_JSON and isinstance( response, dict): self.write(response) self.finish() elif produces == mediatypes.APPLICATION_JSON and isinstance( response, list): self.write(json.dumps(response)) self.finish() elif produces in [mediatypes.APPLICATION_XML, mediatypes.TEXT_XML] and\ isinstance(response, xml.dom.minidom.Document): self.write(response.toxml()) self.finish() else: self.gen_http_error( 500, "Internal Server Error : response is not %s document" % produces) if catch_fire: raise PyRestfulException( "Internal Server Error : response is not %s document" % produces) except Exception as detail: self.gen_http_error(500, "Internal Server Error : %s" % detail) if catch_fire: raise PyRestfulException(detail)
def _exe(self, method): """ Executes the python function for the Rest Service """ request_path = self.request.path path = request_path.split('/') services_and_params = list(filter(lambda x: x!='',path)) content_type = None if 'Content-Type' in self.request.headers.keys(): content_type = self.request.headers['Content-Type'] # Get all funcion names configured in the class RestHandler functions = list(filter(lambda op: hasattr(getattr(self,op),'_service_name') == True and inspect.ismethod(getattr(self,op)) == True, dir(self))) # Get all http methods configured in the class RestHandler http_methods = list(map(lambda op: getattr(getattr(self,op),'_method'), functions)) if method not in http_methods: raise tornado.web.HTTPError(405,'The service not have %s verb'%method) if path[1] not in list(op._path.split('/')[1] for op in list(map(lambda o: getattr(self,o),functions))): raise tornado.web.HTTPError(404,'404 Not Found {}'.format(path[1])) for operation in list(map(lambda op: getattr(self,op), functions)): service_name = getattr(operation,'_service_name') service_params = getattr(operation,'_service_params') # If the _types is not specified, assumes str types for the params params_types = getattr(operation,"_types") or [str]*len(service_params) params_types = params_types + [str]*(len(service_params)-len(params_types)) produces = getattr(operation,'_produces') consumes = getattr(operation,'_consumes') services_from_request = list(filter(lambda x: x in path,service_name)) query_params = getattr(operation,'_query_params') manual_response = getattr(operation,'_manual_response') catch_fire = getattr(operation,'_catch_fire') if operation._method == self.request.method and service_name == services_from_request and len(service_params) + len(service_name) == len(services_and_params): try: params_values = self._find_params_value_of_url(service_name,request_path) + self._find_params_value_of_arguments(operation) p_values = self._convert_params_values(params_values, params_types) if consumes == None and content_type != None: consumes = content_type if consumes == mediatypes.APPLICATION_XML: param_obj = None body = self.request.body if sys.version_info > (3,): body = str(body,'utf-8') if len(body) >0 and params_types[0] in [str]: param_obj = xml.dom.minidom.parseString(body) elif len(body)>0 : param_obj = convertXML2OBJ(params_types[0],xml.dom.minidom.parseString(body).documentElement) if param_obj != None: p_values.append(param_obj) elif consumes == mediatypes.APPLICATION_JSON: param_obj = None body = self.request.body if sys.version_info > (3,): body = str(body,'utf-8') if len(body)>0 and params_types[0] in [dict,str]: param_obj = json.loads(body) elif len(body)>0 : param_obj = convertJSON2OBJ(params_types[0],json.loads(body)) if param_obj != None: p_values.append(param_obj) elif consumes == mediatypes.TEXT_PLAIN: body = self.request.body if len(body) >= 1: if sys.version_info > (3,): body = str(body,'utf-8') if isinstance(body,str): param_obj = body else: param_obj = convertJSON2OBJ(params_types[0],json.loads(body)) p_values.append(param_obj) response = operation(*p_values) if response == None: return if produces != None: self.set_header('Content-Type',produces) if manual_response: return if (produces == mediatypes.APPLICATION_JSON or produces == None) and hasattr(response,'__module__'): response = convert2JSON(response) elif produces == mediatypes.APPLICATION_XML and hasattr(response,'__module__') and not isinstance(response,xml.dom.minidom.Document): response = convert2XML(response) if produces == None and (isinstance(response,dict) or isinstance(response,str)): self.write(response) self.finish() elif produces == None and isinstance(response,list): self.write(json.dumps(response)) self.finish() elif produces == mediatypes.TEXT_PLAIN and isinstance(response,str): self.write(response) self.finish() elif produces == mediatypes.APPLICATION_JSON and isinstance(response,dict): self.write(response) self.finish() elif produces == mediatypes.APPLICATION_JSON and isinstance(response,list): self.write(json.dumps(response)) self.finish() elif produces in [mediatypes.APPLICATION_XML,mediatypes.TEXT_XML] and isinstance(response,xml.dom.minidom.Document): self.write(response.toxml()) self.finish() else: self.gen_http_error(500,'Internal Server Error : response is not %s document'%produces) if catch_fire == True: raise PyRestfulException('Internal Server Error : response is not %s document'%produces) except Exception as detail: self.gen_http_error(500,'Internal Server Error : %s'%detail) if catch_fire == True: raise PyRestfulException(detail)