Example #1
0
    def response_dict(self, request, D, is_batch=False, version_hint='1.0'):
        version = version_hint
        response = self.empty_response(version=version)
        apply_version = {
            '2.0': lambda f, r, p: f(**encode_kw(p)) if type(p) is dict else f(*p),
            '1.1': lambda f, r, p: f(*encode_arg11(p), **encode_kw(encode_kw11(p))),
            '1.0': lambda f, r, p: f(*p)
        }

        try:
            # params: An Array or Object, that holds the actual parameter values 
            # for the invocation of the procedure. Can be omitted if empty.
            if 'params' not in D or not D['params']:
                 D['params'] = []
            if 'method' not in D or 'params' not in D:
                raise InvalidParamsError('Request requires str:"method" and list:"params"')
            if D['method'] not in self.urls:
                raise MethodNotFoundError('Method not found. Available methods: %s' % ('\n'.join(self.urls.keys())))
            
            if 'jsonrpc' in D:
                if str(D['jsonrpc']) not in apply_version:
                    raise InvalidRequestError('JSON-RPC version %s not supported.' % D['jsonrpc'])
                version = request.jsonrpc_version = response['jsonrpc'] = str(D['jsonrpc'])
            elif 'version' in D:
                if str(D['version']) not in apply_version:
                    raise InvalidRequestError('JSON-RPC version %s not supported.' % D['version'])
                version = request.jsonrpc_version = response['version'] = str(D['version'])
            else:
                request.jsonrpc_version = '1.0'
                
            method = self.urls[str(D['method'])]
            if getattr(method, 'json_validate', False):
                validate_params(method, D)

            if 'id' in D and D['id'] is not None: # regular request
                response['id'] = D['id']
                if version in ('1.1', '2.0') and 'error' in response:
                    response.pop('error')
            elif is_batch: # notification, not ok in a batch format, but happened anyway
                raise InvalidRequestError
            else: # notification
                return None, 204

            R = apply_version[version](method, request, D['params'])

            if 'id' not in D or ('id' in D and D['id'] is None): # notification
                return None, 204
            
            encoder = current_app.json_encoder()
            if not sum(map(lambda e: isinstance(R, e), # type of `R` should be one of these or...
                 (dict, str, unicode, int, long, list, set, NoneType, bool))):
                try:
                    rs = encoder.default(R) # ...or something this thing supports
                except TypeError, exc:
                    raise TypeError("Return type not supported, for %r" % R)

            response['result'] = R
            
            status = 200
Example #2
0
def _convert(obj):
    try:
        return obj.__dict__
    except AttributeError:
        return current_app.json_encoder().default(obj)
Example #3
0
    def response_obj(self, request, D, version_hint=JSONRPC_VERSION_DEFAULT):
        version = version_hint
        response = self.empty_response(version=version)
        apply_version = {
            '2.0': self.apply_version_2_0,
            '1.1': self.apply_version_1_1,
            '1.0': self.apply_version_1_0
        }

        try:
            try:
                # determine if an object is iterable?
                iter(D)
            except TypeError as e:
                raise InvalidRequestError(
                    getattr(e, 'message',
                            e.args[0] if len(e.args) > 0 else None))

            # version: validate
            if 'jsonrpc' in D:
                if text_type(D['jsonrpc']) not in apply_version:
                    raise InvalidRequestError(
                        'JSON-RPC version {0} not supported.'.format(
                            D['jsonrpc']))
                version = request.jsonrpc_version = response[
                    'jsonrpc'] = text_type(D['jsonrpc'])
            elif 'version' in D:
                if text_type(D['version']) not in apply_version:
                    raise InvalidRequestError(
                        'JSON-RPC version {0} not supported.'.format(
                            D['version']))
                version = request.jsonrpc_version = response[
                    'version'] = text_type(D['version'])
            else:
                version = request.jsonrpc_version = JSONRPC_VERSION_DEFAULT

            # params: An Array or Object, that holds the actual parameter values
            # for the invocation of the procedure. Can be omitted if empty.
            if 'params' not in D or not D['params']:
                D['params'] = []
            if 'method' not in D or 'params' not in D:
                raise InvalidParamsError(
                    'Request requires str:"method" and list:"params"')
            if D['method'] not in self.urls:
                raise MethodNotFoundError('Method not found. Available methods: {0}' \
                    .format('\n'.join(list(self.urls.keys()))))

            method = self.urls[text_type(D['method'])]
            if getattr(method, 'json_validate', False):
                validate_params(method, D)

            if 'id' in D and D['id'] is not None:  # regular request
                response['id'] = D['id']
                if version in ('1.1', '2.0'):
                    response.pop('error', None)
            else:  # notification
                return None, 204

            R = apply_version[version](method, D['params'])

            if 'id' not in D or ('id' in D
                                 and D['id'] is None):  # notification
                return None, 204

            if isinstance(R, Response):
                if R.status_code == 200:
                    return R, R.status_code
                if R.status_code == 401:
                    raise InvalidCredentialsError(R.status)
                raise OtherError(R.status, R.status_code)

            try:
                # New in Flask version 0.10.
                encoder = current_app.json_encoder()
            except AttributeError:
                encoder = json.JSONEncoder()

            # type of `R` should be one of these or...
            if not sum([isinstance(R, e) for e in \
                    string_types + integer_types + \
                    (float, complex, dict, list, tuple, set, frozenset, NoneType, bool)]):
                try:
                    rs = encoder.default(
                        R)  # ...or something this thing supports
                except TypeError as exc:
                    raise TypeError(
                        'Return type not supported, for {0!r}'.format(R))

            response['result'] = R
            status = 200
        except Error as e:
            response['error'] = e.json_rpc_format
            if version in ('1.1', '2.0'):
                response.pop('result', None)
            status = e.status
        except HTTPException as e:
            other_error = OtherError(e)
            response['error'] = other_error.json_rpc_format
            response['error']['code'] = e.code
            if version in ('1.1', '2.0'):
                response.pop('result', None)
            status = e.code
        except Exception as e:
            other_error = OtherError(e)
            response['error'] = other_error.json_rpc_format
            status = other_error.status
            if version in ('1.1', '2.0'):
                response.pop('result', None)

        # Exactly one of result or error MUST be specified. It's not
        # allowed to specify both or none.
        if version in ('1.1', '2.0') and 'result' in response:
            response.pop('error', None)

        return response, status
Example #4
0
def health_celery_task():
    return current_app.json_encoder().encode(datetime.now()).strip('"')
Example #5
0
    def response_dict(self, request, D, is_batch=False, version_hint='1.0'):
        version = version_hint
        response = self.empty_response(version=version)
        apply_version = {
            '2.0': lambda f, p: f(**encode_kw(p)) if type(p) is dict else f(*p),
            '1.1': lambda f, p: f(*encode_arg11(p), **encode_kw(encode_kw11(p))),
            '1.0': lambda f, p: f(*p)
        }

        try:
            # params: An Array or Object, that holds the actual parameter values 
            # for the invocation of the procedure. Can be omitted if empty.
            if 'params' not in D or not D['params']:
                 D['params'] = []
            if 'method' not in D or 'params' not in D:
                raise InvalidParamsError('Request requires str:"method" and list:"params"')
            if D['method'] not in self.urls:
                raise MethodNotFoundError('Method not found. Available methods: {0}' \
                    .format('\n'.join(list(self.urls.keys()))))
            
            if 'jsonrpc' in D:
                if str(D['jsonrpc']) not in apply_version:
                    raise InvalidRequestError('JSON-RPC version {0} not supported.'.format(D['jsonrpc']))
                version = request.jsonrpc_version = response['jsonrpc'] = str(D['jsonrpc'])
            elif 'version' in D:
                if str(D['version']) not in apply_version:
                    raise InvalidRequestError('JSON-RPC version {0} not supported.'.format(D['version']))
                version = request.jsonrpc_version = response['version'] = str(D['version'])
            else:
                request.jsonrpc_version = '1.0'
                
            method = self.urls[str(D['method'])]
            if getattr(method, 'json_validate', False):
                validate_params(method, D)

            if 'id' in D and D['id'] is not None: # regular request
                response['id'] = D['id']
                if version in ('1.1', '2.0') and 'error' in response:
                    response.pop('error')
            elif is_batch: # notification, not ok in a batch format, but happened anyway
                raise InvalidRequestError
            else: # notification
                return None, 204

            R = apply_version[version](method, D['params'])

            if 'id' not in D or ('id' in D and D['id'] is None): # notification
                return None, 204
            
            encoder = current_app.json_encoder()

            # type of `R` should be one of these or...
            if not sum([isinstance(R, e) for e in \
                    string_types + integer_types + (dict, list, set, NoneType, bool)]):
                try:
                    rs = encoder.default(R) # ...or something this thing supports
                except TypeError as exc:
                    raise TypeError("Return type not supported, for {0!r}".format(R))

            response['result'] = R
            
            status = 200
        
        except Error as e:
            # exception missed by others
            #got_request_exception.connect(log_exception, current_app._get_current_object())

            response['error'] = e.json_rpc_format
            if version in ('1.1', '2.0') and 'result' in response:
                response.pop('result')
            status = e.status
        except HTTPException as e:
            # exception missed by others
            #got_request_exception.connect(log_exception, current_app._get_current_object())

            other_error = OtherError(e)
            response['error'] = other_error.json_rpc_format
            response['error']['code'] = e.code
            if version in ('1.1', '2.0') and 'result' in response:
                response.pop('result')
            status = e.code
        except Exception as e:
            # exception missed by others
            #got_request_exception.connect(log_exception, current_app._get_current_object())

            other_error = OtherError(e)
            response['error'] = other_error.json_rpc_format
            status = other_error.status
            if version in ('1.1', '2.0') and 'result' in response:
                response.pop('result')

        # Exactly one of result or error MUST be specified. It's not
        # allowed to specify both or none.
        if version in ('1.1', '2.0') and 'error' in response and not response['error']:
            response.pop('error')
        
        return response, status
Example #6
0
    def response_obj(self, request, D, version_hint=JSONRPC_VERSION_DEFAULT):
        version = version_hint
        response = self.empty_response(version=version)
        apply_version = {
            '2.0': self.apply_version_2_0,
            '1.1': self.apply_version_1_1,
            '1.0': self.apply_version_1_0
        }

        try:
            try:
                # determine if an object is iterable?
                iter(D)
            except TypeError as e:
                raise InvalidRequestError(getattr(e, 'message', e.args[0] if len(e.args) > 0 else None))

            # version: validate
            if 'jsonrpc' in D:
                if text_type(D['jsonrpc']) not in apply_version:
                    raise InvalidRequestError('JSON-RPC version {0} not supported.'.format(D['jsonrpc']))
                version = request.jsonrpc_version = response['jsonrpc'] = text_type(D['jsonrpc'])
            elif 'version' in D:
                if text_type(D['version']) not in apply_version:
                    raise InvalidRequestError('JSON-RPC version {0} not supported.'.format(D['version']))
                version = request.jsonrpc_version = response['version'] = text_type(D['version'])
            else:
                version = request.jsonrpc_version = JSONRPC_VERSION_DEFAULT

            # params: An Array or Object, that holds the actual parameter values
            # for the invocation of the procedure. Can be omitted if empty.
            if 'params' not in D or not D['params']:
                 D['params'] = []
            if 'method' not in D or 'params' not in D:
                raise InvalidParamsError('Request requires str:"method" and list:"params"')
            if D['method'] not in self.urls:
                raise MethodNotFoundError('Method not found. Available methods: {0}' \
                    .format('\n'.join(list(self.urls.keys()))))

            method = self.urls[text_type(D['method'])]
            if getattr(method, 'json_validate', False):
                validate_params(method, D)

            if 'id' in D and D['id'] is not None: # regular request
                response['id'] = D['id']
                if version in ('1.1', '2.0'):
                    response.pop('error', None)
            else: # notification
                return None, 204

            R = apply_version[version](method, D['params'])

            if 'id' not in D or ('id' in D and D['id'] is None): # notification
                return None, 204

            if isinstance(R, Response):
                if R.status_code == 200:
                    return R, R.status_code
                if R.status_code == 401:
                    raise InvalidCredentialsError(R.status)
                raise OtherError(R.status, R.status_code)

            try:
                # New in Flask version 0.10.
                encoder = current_app.json_encoder()
            except AttributeError:
                encoder = json.JSONEncoder()

            # type of `R` should be one of these or...
            if not sum([isinstance(R, e) for e in \
                    string_types + integer_types + \
                    (float, complex, dict, list, tuple, set, frozenset, NoneType, bool)]):
                try:
                    rs = encoder.default(R) # ...or something this thing supports
                except TypeError as exc:
                    raise TypeError('Return type not supported, for {0!r}'.format(R))

            response['result'] = R
            status = 200
        except Error as e:
            response['error'] = e.json_rpc_format
            if version in ('1.1', '2.0'):
                response.pop('result', None)
            status = e.status
        except HTTPException as e:
            other_error = OtherError(e)
            response['error'] = other_error.json_rpc_format
            response['error']['code'] = e.code
            if version in ('1.1', '2.0'):
                response.pop('result', None)
            status = e.code
        except Exception as e:
            other_error = OtherError(e)
            response['error'] = other_error.json_rpc_format
            status = other_error.status
            if version in ('1.1', '2.0'):
                response.pop('result', None)

        # Exactly one of result or error MUST be specified. It's not
        # allowed to specify both or none.
        if version in ('1.1', '2.0') and 'result' in response:
            response.pop('error', None)

        return response, status
Example #7
0
def health_celery_task():
    # Complicated Flask-specific encoding to reproduce the same output as the
    # /health endpoint (eg.: "Sun, 09 Dec 2018 16:34:41 GMT").
    return current_app.json_encoder().encode(datetime.now()).strip('"')
Example #8
0
def health_celery_task():
    # Complicated Flask-specific encoding to reproduce the same output as the
    # /health endpoint (eg.: "Sun, 09 Dec 2018 16:34:41 GMT").
    return current_app.json_encoder().encode(datetime.now()).strip('"')
Example #9
0
def to_json(value):
    """Jinja filter to address the encoding of special values to json"""
    return app.json_encoder().dumps(value)
Example #10
0
    def response_dict(self, request, D, is_batch=False, version_hint='1.0'):
        version = version_hint
        response = self.empty_response(version=version)
        apply_version = {
            '2.0': lambda f, p: f(**encode_kw(p))
            if type(p) is dict else f(*p),
            '1.1':
            lambda f, p: f(*encode_arg11(p), **encode_kw(encode_kw11(p))),
            '1.0': lambda f, p: f(*p)
        }

        try:
            # params: An Array or Object, that holds the actual parameter values
            # for the invocation of the procedure. Can be omitted if empty.
            if 'params' not in D or not D['params']:
                D['params'] = []
            if 'method' not in D or 'params' not in D:
                raise InvalidParamsError(
                    'Request requires str:"method" and list:"params"')
            if D['method'] not in self.urls:
                raise MethodNotFoundError('Method not found. Available methods: {0}' \
                    .format('\n'.join(list(self.urls.keys()))))

            if 'jsonrpc' in D:
                if text_type(D['jsonrpc']) not in apply_version:
                    raise InvalidRequestError(
                        'JSON-RPC version {0} not supported.'.format(
                            D['jsonrpc']))
                version = request.jsonrpc_version = response[
                    'jsonrpc'] = text_type(D['jsonrpc'])
            elif 'version' in D:
                if text_type(D['version']) not in apply_version:
                    raise InvalidRequestError(
                        'JSON-RPC version {0} not supported.'.format(
                            D['version']))
                version = request.jsonrpc_version = response[
                    'version'] = text_type(D['version'])
            else:
                request.jsonrpc_version = '1.0'

            method = self.urls[text_type(D['method'])]
            if getattr(method, 'json_validate', False):
                validate_params(method, D)

            if 'id' in D and D['id'] is not None:  # regular request
                response['id'] = D['id']
                if version in ('1.1', '2.0') and 'error' in response:
                    response.pop('error')
            elif is_batch:  # notification, not ok in a batch format, but happened anyway
                raise InvalidRequestError
            else:  # notification
                return None, 204

            R = apply_version[version](method, D['params'])
            if asyncio.iscoroutine(R):
                R = (yield from R)

            if 'id' not in D or ('id' in D
                                 and D['id'] is None):  # notification
                return None, 204

            encoder = current_app.json_encoder()

            # type of `R` should be one of these or...
            if not sum([isinstance(R, e) for e in \
                    string_types + integer_types + (dict, list, set, NoneType, bool)]):
                try:
                    rs = encoder.default(
                        R)  # ...or something this thing supports
                except TypeError as exc:
                    raise TypeError(
                        "Return type not supported, for {0!r}".format(R))

            response['result'] = R

            status = 200

        except Error as e:
            # exception missed by others
            #got_request_exception.connect(log_exception, current_app._get_current_object())

            response['error'] = e.json_rpc_format
            if version in ('1.1', '2.0') and 'result' in response:
                response.pop('result')
            status = e.status
        except HTTPException as e:
            # exception missed by others
            #got_request_exception.connect(log_exception, current_app._get_current_object())

            other_error = OtherError(e)
            response['error'] = other_error.json_rpc_format
            response['error']['code'] = e.code
            if version in ('1.1', '2.0') and 'result' in response:
                response.pop('result')
            status = e.code
        except Exception as e:
            # exception missed by others
            #got_request_exception.connect(log_exception, current_app._get_current_object())

            other_error = OtherError(e)
            response['error'] = other_error.json_rpc_format
            status = other_error.status
            if version in ('1.1', '2.0') and 'result' in response:
                response.pop('result')

        # Exactly one of result or error MUST be specified. It's not
        # allowed to specify both or none.
        if version in ('1.1', '2.0'
                       ) and 'error' in response and not response['error']:
            response.pop('error')

        return response, status
Example #11
0
    def response_dict(self, request, D, is_batch=False, version_hint='1.0'):
        version = version_hint
        response = self.empty_response(version=version)
        apply_version = {
            '2.0': lambda f, r, p: f(**encode_kw(p))
            if type(p) is dict else f(*p),
            '1.1':
            lambda f, r, p: f(*encode_arg11(p), **encode_kw(encode_kw11(p))),
            '1.0': lambda f, r, p: f(*p)
        }

        try:
            # params: An Array or Object, that holds the actual parameter values
            # for the invocation of the procedure. Can be omitted if empty.
            if 'params' not in D or not D['params']:
                D['params'] = []
            if 'method' not in D or 'params' not in D:
                raise InvalidParamsError(
                    'Request requires str:"method" and list:"params"')
            if D['method'] not in self.urls:
                raise MethodNotFoundError(
                    'Method not found. Available methods: %s' %
                    ('\n'.join(self.urls.keys())))

            if 'jsonrpc' in D:
                if str(D['jsonrpc']) not in apply_version:
                    raise InvalidRequestError(
                        'JSON-RPC version %s not supported.' % D['jsonrpc'])
                version = request.jsonrpc_version = response['jsonrpc'] = str(
                    D['jsonrpc'])
            elif 'version' in D:
                if str(D['version']) not in apply_version:
                    raise InvalidRequestError(
                        'JSON-RPC version %s not supported.' % D['version'])
                version = request.jsonrpc_version = response['version'] = str(
                    D['version'])
            else:
                request.jsonrpc_version = '1.0'

            method = self.urls[str(D['method'])]
            if getattr(method, 'json_validate', False):
                validate_params(method, D)

            if 'id' in D and D['id'] is not None:  # regular request
                response['id'] = D['id']
                if version in ('1.1', '2.0') and 'error' in response:
                    response.pop('error')
            elif is_batch:  # notification, not ok in a batch format, but happened anyway
                raise InvalidRequestError
            else:  # notification
                return None, 204

            R = apply_version[version](method, request, D['params'])

            if 'id' not in D or ('id' in D
                                 and D['id'] is None):  # notification
                return None, 204

            encoder = current_app.json_encoder()
            if not sum(
                    map(
                        lambda e: isinstance(
                            R, e),  # type of `R` should be one of these or...
                        (dict, str, unicode, int, long, list, set, NoneType,
                         bool))):
                try:
                    rs = encoder.default(
                        R)  # ...or something this thing supports
                except TypeError, exc:
                    raise TypeError("Return type not supported, for %r" % R)

            response['result'] = R

            status = 200