def write_error(self, exception): response = None try: response = self.error_handler.response(self.request, exception) version = self.request.version if self.request else '1.1' self.transport.write(response.output(version)) except RuntimeError: log.error( 'Connection lost before error written @ {}'.format( self.request.ip if self.request else 'Unknown')) except Exception as e: self.bail_out( "Writing error failed, connection closed {}".format(repr(e)), from_error=True) finally: if self.has_log: extra = dict() if isinstance(response, HTTPResponse): extra['status'] = response.status extra['byte'] = len(response.body) else: extra['status'] = 0 extra['byte'] = -1 if self.request: extra['host'] = '%s:%d' % self.request.ip, extra['request'] = '%s %s' % (self.request.method, self.url) else: extra['host'] = 'UNKNOWN' extra['request'] = 'nil' if self.parser and not (self.keep_alive and extra['status'] == 408): netlog.info('', extra=extra) self.transport.close()
def response(self, request, exception): """Fetches and executes an exception handler and returns a response object :param request: Request :param exception: Exception to handle :return: Response object """ handler = self.lookup(exception) response = None try: if handler: response = handler(request=request, exception=exception) if response is None: response = self.default(request=request, exception=exception) except Exception: self.log(format_exc()) if self.debug: url = getattr(request, 'url', 'unknown') response_message = ( 'Exception raised in exception handler "{}" ' 'for uri: "{}"\n{}').format(handler.__name__, url, format_exc()) log.error(response_message) return text(response_message, 500) else: return text('An error occurred while handling an error', 500) return response
def response(self, request, exception): """Fetches and executes an exception handler and returns a response object :param request: Request :param exception: Exception to handle :return: Response object """ handler = self.lookup(exception) response = None try: if handler: response = handler(request=request, exception=exception) if response is None: response = self.default(request=request, exception=exception) except Exception: self.log(format_exc()) if self.debug: url = getattr(request, 'url', 'unknown') response_message = ( 'Exception raised in exception handler "{}" ' 'for uri: "{}"\n{}').format( handler.__name__, url, format_exc()) log.error(response_message) return text(response_message, 500) else: return text('An error occurred while handling an error', 500) return response
def write_response(self, response): """ Writes response content synchronously to the transport. """ try: keep_alive = self.keep_alive self.transport.write( response.output( self.request.version, keep_alive, self.request_timeout)) except AttributeError: log.error( ('Invalid response object for url {}, ' 'Expected Type: HTTPResponse, Actual Type: {}').format( self.url, type(response))) self.write_error(ServerError('Invalid response type')) except RuntimeError: log.error( 'Connection lost before response written @ {}'.format( self.request.ip)) except Exception as e: self.bail_out( "Writing response failed, connection closed {}".format( repr(e))) finally: if not keep_alive: self.transport.close() else: self._last_request_time = current_time self.cleanup()
async def get(self, request, **kwargs): try: shortcuts = self.model.shortcuts response_messages = self.config.response_messages primary_key = kwargs.get(shortcuts.primary_key) include_backrefs = False include_foreign_keys = False if 'backrefs' in request.args and request.args['backrefs'][ 0] == 'true': include_backrefs = True include_foreign_keys = True elif 'foreign_keys' in request.args and request.args[ 'foreign_keys'][0] == 'true': include_foreign_keys = True data = self.get_model(primary_key) if not data: return self.response_json( data=data, status_code=404, message=response_messages.ErrorDoesNotExist.format( primary_key)) else: return self.response_json(data=model_to_dict( data, recurse=include_foreign_keys, backrefs=include_backrefs), status_code=200, message=response_messages.SuccessOk) except Exception as e: log.error(traceback.print_exc()) return self.response_json(message=str(e), status_code=500)
async def put(self, request, **kwargs): valid_request = self.validate_request(request) if valid_request is not True: return valid_request try: shortcuts = self.model.shortcuts response_messages = self.config.response_messages request_data = request.json.items() primary_key = kwargs.get(shortcuts.primary_key) resource = self.get_model(primary_key) if not resource: return self.response_json( data={}, status_code=404, message=response_messages.ErrorDoesNotExist.format( primary_key)) for key, value in request_data: setattr(resource, key, value) resource.save() return self.response_json(data=model_to_dict(resource), status_code=200, message=response_messages.SuccessOk) except Exception as e: log.error(traceback.print_exc()) return self.response_json(message=str(e), status_code=500)
async def stream_response(self, response): """ Streams a response to the client asynchronously. Attaches the transport to the response so the response consumer can write to the response as needed. """ try: keep_alive = ( self.parser.should_keep_alive() and not self.signal.stopped) response.transport = self.transport await response.stream( self.request.version, keep_alive, self.request_timeout) except AttributeError: log.error( ('Invalid response object for url {}, ' 'Expected Type: HTTPResponse, Actual Type: {}').format( self.url, type(response))) self.write_error(ServerError('Invalid response type')) except RuntimeError: log.error( 'Connection lost before response written @ {}'.format( self.request.ip)) except Exception as e: self.bail_out( "Writing response failed, connection closed {}".format( repr(e))) finally: if not keep_alive: self.transport.close() else: self._last_request_time = current_time self.cleanup()
def write_error(self, exception): try: response = self.error_handler.response(self.request, exception) version = self.request.version if self.request else '1.1' self.transport.write(response.output(version)) except RuntimeError: log.error('Connection lost before error written @ {}'.format( self.request.ip if self.request else 'Unknown')) except Exception as e: self.bail_out("Writing error failed, connection closed {}".format( repr(e)), from_error=True) finally: if self.has_log: extra = { 'status': response.status, 'host': '', 'request': str(self.request) + str(self.url) } if response and isinstance(response, HTTPResponse): extra['byte'] = len(response.body) else: extra['byte'] = -1 if self.request: extra['host'] = '%s:%d' % self.request.ip, extra['request'] = '%s %s' % (self.request.method, self.url) netlog.info('', extra=extra) self.transport.close()
def write_response(self, response): keep_alive = (self.parser.should_keep_alive() and not self.signal.stopped) try: self.transport.write( response.output(self.request.version, keep_alive, self.request_timeout)) except AttributeError: log.error(('Invalid response object for url {}, ' 'Expected Type: HTTPResponse, Actual Type: {}').format( self.url, type(response))) self.write_error(ServerError('Invalid response type')) except RuntimeError: log.error('Connection lost before response written @ {}'.format( self.request.ip)) except Exception as e: self.bail_out( "Writing response failed, connection closed {}".format( repr(e))) finally: if not keep_alive: self.transport.close() else: # Record that we received data self._last_request_time = current_time self.cleanup()
def write_error(self, exception): try: response = self.error_handler.response(self.request, exception) version = self.request.version if self.request else '1.1' self.transport.write(response.output(version)) except RuntimeError: log.error( 'Connection lost before error written @ {}'.format( self.request.ip if self.request else 'Unknown')) except Exception as e: self.bail_out( "Writing error failed, connection closed {}".format(repr(e)), from_error=True) finally: if self.has_log: extra = { 'status': response.status, 'host': '', 'request': str(self.request) + str(self.url) } if response and isinstance(response, HTTPResponse): extra['byte'] = len(response.body) else: extra['byte'] = -1 if self.request: extra['host'] = '%s:%d' % self.request.ip, extra['request'] = '%s %s' % (self.request.method, self.url) netlog.info('', extra=extra) self.transport.close()
def bail_out(self, message): """ 记录异常辅助方法 """ exception = ServerError(message) self.write_error(exception) log.error(message)
async def _collect_response(sanic, loop): try: response = await self._local_request(method, uri, *request_args, **request_kwargs) results[-1] = response except Exception as e: log.error('Exception:\n{}'.format(traceback.format_exc())) exceptions.append(e) self.app.stop()
def bail_out(self, message, from_error=False): if from_error or self.transport.is_closing(): log.error(("Transport closed @ {} and exception " "experienced during error handling").format( self.transport.get_extra_info('peername'))) log.debug('Exception:\n{}'.format(traceback.format_exc())) else: exception = ServerError(message) self.write_error(exception) log.error(message)
async def _collect_response(sanic, loop): try: response = await self._local_request( method, uri, *request_args, **request_kwargs) results[-1] = response except Exception as e: log.error( 'Exception:\n{}'.format(traceback.format_exc())) exceptions.append(e) self.app.stop()
def bail_out(self, message, from_error=False): if from_error or self.transport.is_closing(): log.error( ("Transport closed @ {} and exception " "experienced during error handling").format( self.transport.get_extra_info('peername'))) log.debug( 'Exception:\n{}'.format(traceback.format_exc())) else: exception = ServerError(message) self.write_error(exception) log.error(message)
def write_error(self, exception): try: response = self.error_handler.response(self.request, exception) version = self.request.version if self.request else '1.1' self.transport.write(response.output(version)) except RuntimeError: log.error('Connection lost before error written @ {}'.format( self.request.ip)) except Exception as e: self.bail_out( "Writing error failed, connection closed {}".format(e), from_error=True) finally: self.transport.close()
async def stream_response(self, response): """ Streams a response to the client asynchronously. Attaches the transport to the response so the response consumer can write to the response as needed. """ if self._response_timeout_handler: self._response_timeout_handler.cancel() self._response_timeout_handler = None try: keep_alive = self.keep_alive response.transport = self.transport await response.stream(self.request.version, keep_alive, self.keep_alive_timeout) if self.has_log: netlog.info('', extra={ 'status': response.status, 'byte': -1, 'host': '{0}:{1}'.format(self.request.ip[0], self.request.ip[1]), 'request': '{0} {1}'.format(self.request.method, self.request.url) }) except AttributeError: log.error(('Invalid response object for url {}, ' 'Expected Type: HTTPResponse, Actual Type: {}').format( self.url, type(response))) self.write_error(ServerError('Invalid response type')) except RuntimeError: log.error('Connection lost before response written @ {}'.format( self.request.ip)) except Exception as e: self.bail_out( "Writing response failed, connection closed {}".format( repr(e))) finally: if not keep_alive: self.transport.close() else: self._keep_alive_timeout_handler = self.loop.call_later( self.keep_alive_timeout, self.keep_alive_timeout_callback) self._last_response_time = current_time self.cleanup()
async def post(self, request): valid_request = self.validate_request(request) if valid_request is not True: return valid_request try: result = self.model.create(**request.json) return self.response_json( data=model_to_dict(result), status_code=200, message=self.config.response_messages.SuccessRowCreated.format( result.id)) except Exception as e: log.error(traceback.print_exc()) return self.response_json(message=str(e), status_code=500)
def default(self, request, exception): self.log(format_exc()) if issubclass(type(exception), SanicException): return text('Error: {}'.format(exception), status=getattr(exception, 'status_code', 500), headers=getattr(exception, 'headers', dict())) elif self.debug: html_output = self._render_traceback_html(exception, request) response_message = ( 'Exception occurred while handling uri: "{}"\n{}'.format( request.url, format_exc())) log.error(response_message) return html(html_output, status=500) else: return html(INTERNAL_SERVER_ERROR_HTML, status=500)
async def get(self, request, **kwargs): try: response_messages = self.config.response_messages # Verify page is an int try: page = int(request.args.get('page', 1)) except ValueError: return self.response_json( status_code=400, message=response_messages.ErrorTypeInteger.format('page')) include_backrefs = False include_foreign_keys = False if 'backrefs' in request.args and request.args['backrefs'][ 0] == 'true': include_backrefs = True include_foreign_keys = True elif 'foreign_keys' in request.args and request.args[ 'foreign_keys'][0] == 'true': include_foreign_keys = True results = [] data = kwargs.get('filtered_results') total_records = data.count() total_pages = ceil(total_records / self.config.COLLECTION_MAX_RESULTS_PER_PAGE) data = data.paginate(page, self.config.COLLECTION_MAX_RESULTS_PER_PAGE) for row in data: results.append( model_to_dict(row, recurse=include_foreign_keys, backrefs=include_backrefs)) return self.response_json(data=results, status_code=200, message=response_messages.SuccessOk, page=page, total_pages=total_pages) except Exception as e: log.error(traceback.print_exc()) return self.response_json(message=str(e), status_code=500)
def default(self, request, exception): self.log(format_exc()) if issubclass(type(exception), SanicException): return text( 'Error: {}'.format(exception), status=getattr(exception, 'status_code', 500), headers=getattr(exception, 'headers', dict()) ) elif self.debug: html_output = self._render_traceback_html(exception, request) response_message = ( 'Exception occurred while handling uri: "{}"\n{}'.format( request.url, format_exc())) log.error(response_message) return html(html_output, status=500) else: return html(INTERNAL_SERVER_ERROR_HTML, status=500)
async def interface(request): # get var from request args signature = request.raw_args.get('signature', '') timestamp = request.raw_args.get('timestamp', '') nonce = request.raw_args.get('nonce', '') echostr = request.raw_args.get('echostr', '') msg_signature = request.raw_args.get('msg_signature', '') encrypt_type = request.raw_args.get('encrypt_type', '') try: check_signature(config.WECHAT_TOKEN, signature, timestamp, nonce) except InvalidSignatureException: # 处理异常情况或忽略 netlog.error('>>> {},{}'.format(request.raw_args, '验证异常')) return response.text('验证异常') else: if request.method == 'GET': # 服务器配置 log.info('>>> {},{}'.format(request.raw_args, '验证ok')) return response.text(echostr) else: # 公众号被动接受消息 if len(request.body) == 0: return response.text('') # 加密方式 if encrypt_type == 'aes': crypto = WeChatCrypto(config.WECHAT_TOKEN, config.WECHAT_ENCODING_AES_KEY, config.WECHAT_APPID) try: decrypted_xml = crypto.decrypt_message( request.body, msg_signature, timestamp, nonce) except (InvalidAppIdException, InvalidSignatureException): # to-do: 处理异常或忽略 log.error('>>> 加密处理异常') return response.text('') else: return response.text( get_resp_message(request, decrypted_xml, mode='aes')) else: # 纯文本方式 return response.text(get_resp_message(request, request.body))
def write_response(self, response): try: keep_alive = (self.parser.should_keep_alive() and not self.signal.stopped) self.transport.write( response.output(self.request.version, keep_alive, self.request_timeout)) except RuntimeError: log.error('Connection lost before response written @ {}'.format( self.request.ip)) except Exception as e: self.bail_out( "Writing response failed, connection closed {}".format(e)) finally: if not keep_alive: self.transport.close() else: # Record that we received data self._last_request_time = current_time self.cleanup()
def write_response(self, response): """ Writes response content synchronously to the transport. """ try: keep_alive = self.keep_alive self.transport.write( response.output(self.request.version, keep_alive, self.request_timeout)) if self.has_log: netlog.info('', extra={ 'status': response.status, 'byte': len(response.body), 'host': '{0}:{1}'.format(self.request.ip[0], self.request.ip[1]), 'request': '{0} {1}'.format(self.request.method, self.request.url) }) except AttributeError: log.error(('Invalid response object for url {}, ' 'Expected Type: HTTPResponse, Actual Type: {}').format( self.url, type(response))) self.write_error(ServerError('Invalid response type')) except RuntimeError: log.error('Connection lost before response written @ {}'.format( self.request.ip)) except Exception as e: self.bail_out( "Writing response failed, connection closed {}".format( repr(e))) finally: if not keep_alive: self.transport.close() else: self._last_request_time = current_time self.cleanup()
async def stream_response(self, response): """ Streams a response to the client asynchronously. Attaches the transport to the response so the response consumer can write to the response as needed. """ try: keep_alive = self.keep_alive response.transport = self.transport await response.stream( self.request.version, keep_alive, self.request_timeout) if self.has_log: netlog.info('', extra={ 'status': response.status, 'byte': -1, 'host': '{0}:{1}'.format(self.request.ip[0], self.request.ip[1]), 'request': '{0} {1}'.format(self.request.method, self.request.url) }) except AttributeError: log.error( ('Invalid response object for url {}, ' 'Expected Type: HTTPResponse, Actual Type: {}').format( self.url, type(response))) self.write_error(ServerError('Invalid response type')) except RuntimeError: log.error( 'Connection lost before response written @ {}'.format( self.request.ip)) except Exception as e: self.bail_out( "Writing response failed, connection closed {}".format( repr(e))) finally: if not keep_alive: self.transport.close() else: self._last_request_time = current_time self.cleanup()
def response(self, request, exception): """Fetches and executes an exception handler and returns a response object :param request: Request :param exception: Exception to handle :return: Response object """ handler = self.handlers.get(type(exception), self.default) try: response = handler(request=request, exception=exception) except Exception: self.log(format_exc()) if self.debug: response_message = ( 'Exception raised in exception handler "{}" ' 'for uri: "{}"\n{}').format(handler.__name__, request.url, format_exc()) log.error(response_message) return text(response_message, 500) else: return text('An error occurred while handling an error', 500) return response
async def delete(self, request, **kwargs): try: shortcuts = self.model.shortcuts response_messages = self.config.response_messages primary_key = kwargs.get(shortcuts.primary_key) resource = self.get_model(primary_key) if not resource: return self.response_json( data={}, status_code=404, message=response_messages.ErrorDoesNotExist.format( primary_key)) resource.delete_instance() return self.response_json( status_code=200, message=response_messages.SuccessRowDeleted.format( primary_key)) except Exception as e: log.error(traceback.print_exc()) return self.response_json(message=str(e), status_code=500)
module_name = ".".join(module_parts[:-1]) app_name = module_parts[-1] module = import_module(module_name) app = getattr(module, app_name, None) if not isinstane(ap, Sanic): raise ValueEror("Module is not a Sanci app, it is a {}") app.run( host=args.host, port=args.port, ) except ImportError: log.error("No Moudle name {} found.\n") except ValueErrlr as e: log.error("{}".format(e)) from sancci.app import Sanic from sanic.response import html app = Sanic() @app.route('/', methods=['GET']) async def index(request): return html("<h1> This is index</h1>")
args = parser.parse_args() try: module_parts = args.module.split(".") module_name = ".".join(module_parts[:-1]) app_name = module_parts[-1] module = import_module(module_name) app = getattr(module, app_name, None) if not isinstance(app, Sanic): raise ValueError("Module is not a Sanic app, it is a {}. " "Perhaps you meant {}.app?".format( type(app).__name__, args.module)) if args.cert is not None or args.key is not None: ssl = {'cert': args.cert, 'key': args.key} else: ssl = None app.run(host=args.host, port=args.port, workers=args.workers, debug=args.debug, ssl=ssl) except ImportError: log.error( "No module named {} found.\n" " Example File: project/sanic_server.py -> app\n" " Example Module: project.sanic_server.app".format(module_name)) except ValueError as e: log.error("{}".format(e))
def wrapped(self, request, *args, **kwargs): model = self.model shortcuts = model.shortcuts fields = shortcuts.fields response_messages = self.config.response_messages query = model.select() # Iterate over args and split the filters for key, value in request.args.items(): # skip over include foreign_keys flag if key == 'foreign_keys' or key == 'backrefs' or key == 'page': continue filter_parts = key.split('__') field = filter_parts[0] comparison = '=' value = value[ 0] # Value comes in as an array with a single argument? TODO: Re-evaluate this! # If the length is 2, then there is a filter component if len(filter_parts) == 2: comparison = filter_parts[1] # Validate that a supported comparison is used if comparison not in self.config.FILTER_OPTIONS: return self.response_json( status_code=400, message=response_messages.ErrorInvalidFilterOption.format( comparison, shortcuts.FILTER_OPTIONS)) # Validate that the field is part of the table if field not in fields: return self.response_json( status_code=400, message=response_messages.ErrorInvalidField.format( key, fields.keys())) log.error(value) # Validate that the value is the correct type if comparison in ['in', 'notin']: value = value.split(',') else: value = [value] if comparison != 'null': for item in value: field_type_invalid = _validate_field_type( self, fields.get(field), item) if field_type_invalid: return field_type_invalid model_field = getattr(model, field) # Build the query from comparisons if comparison == '=': query = query.where(model_field == value) elif comparison == 'null': query = query.where( model_field.is_null(True if value == 1 else False)) elif comparison == 'startswith': query = query.where(model_field.startswith(value)) elif comparison == 'contains': query = query.where(model_field.contains(value)) elif comparison == 'lt': query = query.where(model_field < value) elif comparison == 'lte': query = query.where(model_field <= value) elif comparison == 'gt': query = query.where(model_field > value) elif comparison == 'gte': query = query.where(model_field >= value) elif comparison == 'in': query = query.where(model_field << value) elif comparison == 'notin': query = query.where(~(model_field << value)) kwargs['filtered_results'] = query return func(self, request, *args, **kwargs)