Example #1
0
    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()))
Example #2
0
 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
Example #3
0
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)
Example #4
0
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
Example #5
0
 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()
Example #6
0
 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()
Example #7
0
 def __init__(self, **kwargs):
     self.__dict__.update(kwargs)
     self.log = JLog().bind()
Example #8
0
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'
Example #9
0
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',
                    },
                ],
Example #10
0
 def __init__(self):
     self.log = JLog().bind()
Example #11
0
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
Example #12
0
#     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')
Example #13
0
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'
            }
        }