class log_runtime(ContextDecorator): def __init__(self, **kwargs): self.__dict__.update(kwargs) self.log = JLog().bind() def __enter__(self): self.start_time = time.time() return self def __exit__(self, typ, val, traceback): # Note: typ, val and traceback will only be not None # If an exception occured self.log.info("{}: {}".format(self.__dict__.get('label', 'default'), time.time() - self.start_time)) return False
# for style in range(8): # for fg in range(30, 38): # s1 = '' # for bg in range(40, 48): # format = ';'.join([str(style), str(fg), str(bg)]) # s1 += '\x1b[%sm %s \x1b[0m' % (format, format) # print(s1) # print('\n') def test(): raise Exception('haha') def test1(): test() # raise Exception('haha') if __name__ == '__main__': log = JLog().setup().bind() log.debug('hehe') log.info('hehe') log.error('noshow') log.critical('hehe') try: test1() except Exception as e: log.error_trace('error trace') log.critical_trace('critical trace')
class SwaggerServer: def __init__(self, errors=None, cors_origin=None): self.default_content_type = 'application/json' self.specs = {} # Meta() self.custom_error_map = errors self.op_loader = OperatorLoader() self.log = JLog().bind() self.cors_origin = cors_origin def __call__(self, req, resp): # , **kwargs): self.log.debug('remote_addr:{}, uri:{}, method:{}'.format( req.remote_addr, req.uri, req.method)) self.process(req, resp) def load_specs(self, swagger_spec): self.specs = SpecLoader(log=self.log).load_specs(swagger_spec) self.basePath = self.specs['basePath'] def process(self, req, resp): if req.method == 'OPTIONS': if self.cors_origin is not False: self.process_preflight_request(req, resp) response_body = '\n' response_body += 'nothing here\n\n' resp.body = response_body resp.status = falcon.HTTP_200 return try: if self.cors_origin is not False: self.process_preflight_request(req, resp) self.dispatch(req, resp) except Exception as e: self.log.error_trace('process failed') error_type = type(e) error_map = { falcon.errors.HTTPNotFound: http_falcon_handler, falcon.errors.HTTPMissingParam: http_falcon_handler, falcon.errors.HTTPInvalidParam: http_falcon_handler, falcon.errors.HTTPInternalServerError: http_falcon_handler, } if self.custom_error_map: error_map.update(self.custom_error_map) error_func = error_map.get(error_type) if error_func: error_func(req, resp, e) else: default_error_handler(req, resp, e) def process_preflight_request(self, req, resp): self.log.info("option request: ".format(req.relative_uri)) resp.set_header('Vary', 'Origin') resp.set_header('Access-Control-Allow-Origin', self.allowed_origin(req)) resp.set_header('Access-Control-Allow-Credentials', 'true') resp.set_header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS') resp.set_header( 'Access-Control-Allow-Headers', 'Authorization, X-Auth-Token, Keep-Alive, Users-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type' ) # resp.set_header('Access-Control-Max-Age', 1728000) # 20 days def allowed_origin(self, req): if type(self.cors_origin) == str: return self.cors_origin host = req.env['SERVER_NAME'] + ':' + req.env['SERVER_PORT'] return req.env['wsgi.url_scheme'] + '://' + host def dispatch(self, req, resp): base_before, base_after, base_excp, base_final = self.op_loader.load_base( self.specs) for uri_regex, spec in self.specs.items(): # try: route_signature = '/' + req.method.lower() + req.relative_uri if route_signature.find('?') > 0: route_signature = route_signature[:route_signature.find('?')] if type(uri_regex) == str: continue spec['route_signature'] = route_signature req.spec = copy.deepcopy(spec) match = uri_regex.match(route_signature) if match: handler, params, before, after, excp, final, mode = self.op_loader.load( req=req, spec=spec, matched_uri=match) handler_return = None try: if base_before: base_before(req=req, resp=resp, **params) if before: before(req=req, resp=resp, **params) if mode == 'raw': handler_return = handler(req=req, resp=resp) else: if mode == 'more': handler_return = handler(req=req, resp=resp, **params) else: handler_return = handler(**params) content_type = self.produces( spec.get('produces'), self.specs.get('produces')) self.process_response(req, resp, handler_return, content_type) if after: after(req=req, resp=resp, response=handler_return, **params) if base_after: base_after(req=req, resp=resp, **params) except Exception as e: throw_out = True if base_excp is not None: throw_out = base_excp(req=req, resp=resp, error=e) if excp is not None: throw_out = excp(req=req, resp=resp, error=e) if throw_out: raise e finally: if final: final(req=req, resp=resp, response=handler_return, **params) if base_final: base_final(req=req, resp=resp, **params) return # except falcon.HTTPInvalidParam as e: # self.log.error_trace("http invalid param: {}".format(e)) # raise e # except Exception as e: # self.log.error_trace("process error: {}".format(e)) # raise falcon.HTTPInternalServerError(title=str(type(e)), description=str(e)) self.log.info( "url does not match any route signature or match error: {}".format( route_signature)) raise falcon.HTTPNotFound() def process_response(self, req, resp, handler_return, content_type='application/json'): # content_type = 'text/plain' if handler_return is None: return if type(handler_return) == tuple: data = handler_return[0] http_code = handler_return[1] if len(handler_return) > 2: content_type = handler_return[2] else: data = handler_return http_code = falcon.HTTP_200 # if type(data) == dict or type(data) == list: # content_type = 'application/json' if resp.body: try: pre_body = json.loads(resp.body) except Exception as e: pre_body = resp.body if type(pre_body) == dict: if 'json' in content_type: pre_body.update(data) resp.body = json.dumps(pre_body, indent=2, ensure_ascii=False) else: resp.body = json.dumps(pre_body, ensure_ascii=False) + data else: resp.body = pre_body + json.dumps( data, indent=2, ensure_ascii=False ) if 'json' in content_type else json.dumps( pre_body, indent=2, ensure_ascii=False) + str(data) else: if 'json' in content_type or type(data) == dict: resp.body = json.dumps(data, indent=2, ensure_ascii=False) elif type(data) == str or type(data) == bytes: resp.body = data else: resp.body = str(data) resp.content_type = content_type resp.status = http_code def produces(self, mp=None, gp=None): if mp is not None: return mp[0] if gp is not None: return gp[0] return 'application/json'
class FALSY: def __init__(self, falcon_api=None, static_path='static', static_dir='static', log_config=None): if log_config is None: self.log = JLog().setup().bind() else: self.log = JLog().setup(config=log_config).bind() self.log.info( cc('falsy init', fore=77, styles=['italic', 'underlined', 'reverse'])) self.api = self.falcon_api = falcon_api or falcon.API() self.static_path = static_path.strip('/') self.static_dir = static_dir if os.path.isdir(static_dir) else '.' self.api = CommonStaticMiddleware(self.falcon_api, static_dir=self.static_dir, url_prefix=self.static_path) self.log.info('common static middleware loaded\n\t{}'.format( 'url_prefix(static_path):' + reverse() + self.static_path + rreverse() + ', static_dir:' + reverse() + self.static_dir + rreverse())) def wsgi(self, app, url_prefix='/wsgi'): self.api = CommonWSGIMiddleware(self.api, app, url_prefix=url_prefix) self.log.info( 'common wsgi middleware loaded\n\t{}'.format('url_prefix:' + self.static_path)) return self def swagger(self, filename, ui=True, new_file=None, ui_language='en', theme='normal', errors=None, cors_origin=None, api_url=None): server = SwaggerServer(errors=errors, cors_origin=cors_origin) self.log.info('swagger server init') swagger_file = filename.replace('/', '_') if swagger_file.endswith('yml') or swagger_file.endswith('yaml'): new_file = new_file or swagger_file new_file = new_file.replace('.yaml', '.json') new_file = new_file.replace('.yml', '.json') new_path = self.static_dir + '/' + new_file with open(filename, 'r') as f: config = yaml.load(f, Loader) server.load_specs(config) with open(new_path, 'w') as fw: config = self.remove_error_info(config) json.dump(config, fw, sort_keys=True, indent=4) self.log.info( 'swagger file generated(from yaml file)\n\t{}'.format( 'new_path:' + reverse() + new_path + rreverse())) else: new_file = new_file or swagger_file new_path = self.static_dir + '/' + new_file with open(filename, 'r') as fr: config = fr.read() server.load_specs(config) with open(new_path, 'w') as fw: config = json.loads(self.remove_error_info(config)) json.dump(config, fw, sort_keys=True, indent=4) self.log.info( 'swagger file generated(from json file)\n\t{}'.format( 'new_path:' + reverse() + new_path + rreverse())) path = server.basePath path = path.lstrip('/') if path else 'v0' self.falcon_api.add_sink(server, '/' + path) self.log.info( 'swagger server sinked\n\t{}'.format('path:' + reverse() + path + rreverse())) if ui: self.api = SwaggerUIStaticMiddleware( self.api, swagger_file=self.static_path + '/' + new_file, url_prefix=path, language=ui_language, theme=theme, api_url=api_url) self.log.info('swagger ui static middleware loaded\n\t{}'.format( 'url_prefix(static_path):' + reverse() + self.static_path) + rreverse()) return self # deprecated def begin_api(self, api_prefix=None, errors=None): pass # deprecated def end_api(self): pass def remove_error_info(self, d): if not isinstance(d, (dict, list)): return d if isinstance(d, list): return [self.remove_error_info(v) for v in d] return { k: self.remove_error_info(v) for k, v in d.items() if k not in { 'validationId', 'beforeId', 'afterId', 'exceptionId', 'operationId', 'finalId', 'operationMode' } }