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 __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 before_get_it(req, resp, name): log = JLog().bind() try: parsed_args = parser.parse(hello_args, req=req) except HTTPError as e: log.error_trace(str(e.errors)) raise Exception(e.errors)
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
def __init__(self, app, static_dir='dist', url_prefix='static'): self.app = app self.static_dir = static_dir self.url_prefix = url_prefix.lstrip('/') self.path_dir = os.path.abspath(static_dir) self.log = JLog().bind()
def __init__(self, falcon_api, app, url_prefix='wsgi'): self.falcon_api = falcon_api self.app = app self.url_prefix = url_prefix.lstrip('/') self.log = JLog().bind()
def __init__(self, **kwargs): self.__dict__.update(kwargs) self.log = JLog().bind()
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'
from falsy.jlog.jlog import JLog from falsy.loader import func, task log = JLog().bind() def post_it(name): log.debug('post it') payload = { 'type': 'normal', 'tasks': [ { "args": [ { 'url': 'http://www.baidu.com', 'dns_servers': '114.114.114.114', 'post_func': 'demo.celery.task.tasks.post_func' }, { 'url': 'http://www.douban.com', 'dns_servers': '114.114.114.114' }, ], "ids": ["demo.celery.task.tasks.crawl"], }, { "args": [ { 'url': 'http://www.google.com', }, ],
def __init__(self): self.log = JLog().bind()
class OperatorLoader: def __init__(self): self.log = JLog().bind() def load_base(self, spec): bid = spec.get('beforeId') aid = spec.get('afterId') eid = spec.get('exceptionId') fid = spec.get('finalId') return bid, aid, eid, fid def load(self, req, spec, matched_uri): vid = spec.get('validationId') aid = spec.get('afterId') oid = spec.get('operationId') bid = spec.get('beforeId') eid = spec.get('exceptionId') fid = spec.get('finalId') omode = spec.get('operationMode') return oid, self.load_params(req, spec.get('parameters'), matched_uri, spec, vid), bid, aid, eid, fid, omode def load_params(self, req, params, matched_uri, spec, validator): if params: results = {} for param in params: name = param.get('name') in_ = param.get('in') default = param.get('default') required = param.get('required') # value = None if in_ == 'query': value = self.param_in_query(req, param) elif in_ == 'path': value = self.param_in_path(matched_uri, param) elif in_ == 'body': value = self.param_in_body(req, spec, param) elif in_ == 'header': value = self.param_in_header(req, spec, param) else: value = None if default and value is None: value = default vid = param.get('validationId') self.custom_validate(vid, value) if required or value is not None: results[name] = value if len(results) == 0: self.custom_validate_all(validator) else: self.custom_validate_all(validator, **results) return results self.custom_validate_all(validator) return {} def custom_validate(self, vid, value): validator = vid # get_function_from_name(vid) validated = None try: if validator: validated = validator(value) except Exception as e: self.log.error_trace( 'custom validtion failed,vid: {}, value: {}'.format( vid, value)) raise falcon.HTTPInvalidParam('validation failed, value:', str(value)) if type(validated) == list or type(validated) == tuple: va = validated[0] ext = validated[1] if va is None or va is False: raise falcon.HTTPInvalidParam( 'invalid param(custom validation), value:', str(value) + ' info:' + ext) else: if validated is False: raise falcon.HTTPInvalidParam( 'invalid param(custom validation), value:', str(value)) def custom_validate_all(self, vid, **kwargs): validator = vid # get_function_from_name(vid) validated = None try: if validator: validated = validator( **kwargs) if len(kwargs) > 0 else validator(**kwargs) except Exception as e: raise falcon.HTTPInvalidParam('validation failed, values:', str(kwargs)) if type(validated) == list or type(validated) == tuple: va = validated[0] ext = validated[1] if va is None or va is False: raise falcon.HTTPInvalidParam( 'invalid param(custom validation all), values:', str(kwargs) + ' info:' + ext) else: if validated is False: raise falcon.HTTPInvalidParam( 'invalid param(custom validation all), values:', str(kwargs)) def param_in_query(self, req, param): name = param.get('name') type_ = param.get('type') default_func = lambda p: req.get_param(p ) if type_ is not None else None check_funcs = { 'string': lambda p: req.get_param(p), 'password': lambda p: req.get_param(p), 'byte': lambda p: base64.b64decode(req.get_param(p)), 'integer': lambda p: req.get_param_as_int(p), 'long': lambda p: req.get_param_as_int(p), 'float': lambda p: float(req.get_param(p)), 'double': lambda p: float(req.get_param(p)), 'array': lambda p: req.get_param_as_dict(p), 'object': lambda p: req.get_param_as_dict(p), 'boolean': lambda p: req.get_param_as_bool(p), } value = None try: value = check_funcs.get(type_, default_func)(name) self.log.debug( 'param in query - name: {}, type: {}, value: {}'.format( name, type_, value)) except ValueError as e: self.log.error_trace( 'value error when check param in query - name: {}, type: {}, value: {}' .format(name, type_, value)) raise falcon.HTTPInvalidParam('invalid param in query', name) if param.get('required') and value is None: raise falcon.HTTPMissingParam(name) return value def param_in_path(self, matched_uri, param): type_ = param.get('type') name = param.get('name') value = matched_uri.groupdict().get(name) self.log.debug(value) default_func = lambda v: v if type_ is not None else None check_funcs = { 'string': lambda v: str(v), 'password': lambda v: str(v), 'byte': lambda v: base64.b64decode(str(v)), 'integer': lambda v: int(v), 'long': lambda v: int(v), 'float': lambda v: float(v), 'double': lambda v: float(v), 'boolean': lambda v: bool(v), } if param.get('required') and value is None: raise falcon.HTTPMissingParam(name) try: value = check_funcs.get(type_, default_func)(value) self.log.debug( 'param in path - name: {}, type: {}, value: {}'.format( name, type_, value)) except ValueError as e: self.log.error_trace( 'value error when check param in path - name: {}, type: {}, value: {}' .format(name, type_, value)) raise falcon.HTTPInvalidParam('invalid param in path', name) return value def param_in_header(self, req, spec, param): headers = req.headers name = param.get('name').upper().replace('_', '-') type_ = param.get('type') value = headers.get(name) if param.get('required') and value is None: raise falcon.HTTPMissingParam(name) default_func = lambda v: v if type_ is not None else None check_funcs = { 'string': lambda v: str(v), 'password': lambda v: str(v), 'byte': lambda v: base64.b64decode(str(v)), 'integer': lambda v: int(v), 'long': lambda v: int(v), 'float': lambda v: float(v), 'double': lambda v: float(v), 'boolean': lambda v: bool(v), 'array': json_check, 'object': json_check, } try: value = check_funcs.get(type_, default_func)(value) self.log.debug( 'param in header - name: {}, type: {}, value: {}'.format( name, type_, value)) except ValueError as e: self.log.error_trace( 'value error when check param in header - name: {}, type: {}, value: {}' .format(name, type_, value)) raise falcon.HTTPInvalidParam('invalid param in header', name + ':' + value) if param.get('required') and value is None: raise falcon.HTTPMissingParam(name) return value def param_in_body(self, req, spec, param): body = req.stream.read().decode('utf-8') schema = spec.get('schema') name = param.get('name') type_ = schema.get('type') value = body if param.get('required') and body is None: raise falcon.HTTPMissingParam(name) default_func = lambda v: v check_funcs = { 'string': lambda v: str(v), 'password': lambda v: str(v), 'byte': lambda v: base64.b64decode(str(v)), 'integer': lambda v: int(v), 'long': lambda v: int(v), 'float': lambda v: float(v), 'double': lambda v: float(v), 'boolean': lambda v: bool(v), 'array': json_check, 'object': json_check, } try: if 'allOf' in schema: value = check_funcs.get(type_, json_check)(value) else: value = check_funcs.get(type_, default_func)(value) self.log.debug( 'param in body - name: {}, type: {}, value: {}'.format( name, type_, value)) except ValueError as e: self.log.error_trace( 'value error when check param in body - name: {}, type: {}, value: {}' .format(name, type_, value)) raise falcon.HTTPInvalidParam('invalid param in body', name) return value
# 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 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' } }