def check_spec_match(self, method_name, kwargs): if method_name not in self._specs: self._specs[method_name] = func_spec.FuncSpec(getattr(self, method_name)) try: self._specs[method_name].match_and_convert(kwargs) except TypeError as exc: raise hammock.exceptions.BadRequest('Bad arguments: {}'.format(exc))
def test_func_spec(self): spec = func_spec.FuncSpec(test_func) self.assertListEqual(spec.args, ['an_int', 'a_string', 'a_uuid', 'an_arg_without_type', 'dict_arg']) self.assertDictEqual(spec.kwargs, { 'a_default_bool': None, 'a_default_bool_true': True, 'a_default_bool_false': False, }) self.assertEqual(spec.doc, '\nThis is a test function\nSecond line doc') self.assertEqual(spec.args_info['an_int'].convert, converters.to_int) self.assertEqual(spec.args_info['a_string'].convert, converters.to_str) self.assertEqual(spec.args_info['a_uuid'].convert, converters.to_uuid) self.assertEqual(spec.args_info['a_default_bool'].convert, converters.to_bool) self.assertEqual(spec.args_info['a_default_bool_true'].convert, converters.to_bool) self.assertEqual(spec.args_info['a_default_bool_false'].convert, converters.to_bool) self.assertEqual(spec.args_info['a_default_bool'].type_name, 'bool') self.assertEqual(spec.args_info['a_default_bool_true'].type_name, 'bool[True]') self.assertEqual(spec.args_info['a_default_bool_false'].type_name, 'bool[False]') self.assertEqual(spec.args_info['dict_arg'].convert, converters.to_dict) self.assertEqual(spec.args_info['kwargs_parameter'].convert, converters.to_dict) self.assertEqual(spec.args_info['an_int'].doc, 'integer value.') self.assertEqual(spec.args_info['a_string'].doc, 'string value.\nsecond line doc') self.assertEqual(spec.args_info['a_uuid'].doc, 'uuid value.') self.assertEqual(spec.returns.convert, converters.to_dict) self.assertEqual(spec.returns.doc, 'return value')
def client_methods_properties(resource_object, paths): methods = [] for method in resource_object.iter_route_methods(wrappers.Route): derivative_methods = method.client_methods or {method.__name__: None} for method_name, method_defaults in six.iteritems(derivative_methods): method_defaults = method_defaults or {} url = '/'.join(paths + [resource_object.path(), method.path]) args = [arg for arg in method.spec.args if arg not in method_defaults] kwargs = method.spec.kwargs keywords = method.spec.keywords doc_string = inspect.getdoc(method) if method_defaults and hasattr(resource_object, method_name): sub_method = getattr(resource_object, method_name) doc_string = inspect.getdoc(sub_method) sub_spec = func_spec.FuncSpec(sub_method) args = sub_spec.args kwargs = sub_spec.kwargs keywords = sub_spec.keywords methods.append(dict( method_name=method_name, method=method.method, url=method.path, args=args, kwargs=kwargs, url_kw=[arg for arg in method.spec.args if "{{{}}}".format(arg) in url], defaults=method_defaults, success_code=method.success_code, keywords=keywords, doc_string=doc_string, keyword_map=method.keyword_map, )) return methods
def __init__( self, func, path, exception_handler=None, dest=None, pre_process=None, post_process=None, trim_prefix=False ): """ Create a decorator of a method in a resource class :param func: a function to decorate :param path: url path of the function :param exception_handler: a specific handler for exceptions. :param dest: a hostname + path to pass the request to. :param pre_process: a method to invoke on the request before process. :param post_process: a method to invoke on the request after process. :param trim_prefix: a prefix to trim from the path. :return: the func, decorated """ self.func = func self.spec = func_spec.FuncSpec(func) self._resource = None # Can be determined only after resource class instantiation. self.path = path self.exception_handler = exception_handler self.dest = dest self.pre_process = pre_process self.post_process = post_process self.trim_prefix = trim_prefix self.__name__ = func.__name__ self.__doc__ = func.__doc__ # If it is a proxy, make sure function is valid. if self.dest is not None \ and not common.is_valid_proxy_func(func): raise Exception("Proxy function %s is not empty and not a generator", func.__name__)
def factory(func, column_order=None, column_colors=None): spec = func_spec.FuncSpec(func) overrides = { 'func': func, 'column_order': column_order or [], 'column_colors': column_colors or {}, } if spec.returns: if spec.returns.type_name == 'list': return type(func.__name__, (CommandList, ), overrides) elif spec.returns.type_name == 'file': return type(func.__name__, (CommandFile, ), overrides) return type(func.__name__, (CommandItem, ), overrides)
def __init__(self, *args, **kwargs): super(Command, self).__init__(*args, **kwargs) self.spec = func_spec.FuncSpec(self.func) self.__doc__ = self._get_doc()