@classmethod
def endpoints(cls):
+ # pylint: disable=too-many-branches
def isfunction(m):
return inspect.isfunction(m) or inspect.ismethod(m)
if methods:
result.append((methods, None, '_element', args))
+ for attr, val in inspect.getmembers(cls, predicate=isfunction):
+ if hasattr(val, '_collection_method_'):
+ result.append(
+ (val._collection_method_, attr, '_handle_detail_method', []))
+
+ for attr, val in inspect.getmembers(cls, predicate=isfunction):
+ if hasattr(val, '_resource_method_'):
+ res_params = [":{}".format(arg) for arg in args]
+ url_suffix = "{}/{}".format("/".join(res_params), attr)
+ result.append(
+ (val._resource_method_, url_suffix, '_handle_detail_method', []))
+
return result
@cherrypy.expose
def _element(self, *vpath, **params):
return self._rest_request(True, *vpath, **params)
+ def _handle_detail_method(self, *vpath, **params):
+ method = getattr(self, cherrypy.request.path_info.split('/')[-1])
+
+ if cherrypy.request.method not in ['GET', 'DELETE']:
+ method = RESTController._takes_json(method)
+
+ method = RESTController._returns_json(method)
+
+ cherrypy.response.status = 200
+
+ return method(*vpath, **params)
+
def _rest_request(self, is_element, *vpath, **params):
method_name, status_code = self._method_mapping[
(cherrypy.request.method, is_element)]
ret = func(*args, **kwargs)
return json.dumps(ret).encode('utf8')
return inner
+
+ @staticmethod
+ def resource(methods=None):
+ def _wrapper(func):
+ func._resource_method_ = methods
+ return func
+ return _wrapper
+
+ @staticmethod
+ def collection(methods=None):
+ def _wrapper(func):
+ func._collection_method_ = methods
+ return func
+ return _wrapper
# pylint: disable=unused-argument
time.sleep(TaskTest.sleep_time)
+ @Task('task/foo', ['{param}'])
+ @RESTController.collection(['POST'])
+ @RESTController.args_from_json
+ def foo(self, param):
+ return {'my_param': param}
+
+ @Task('task/bar', ['{key}', '{param}'])
+ @RESTController.resource(['PUT'])
+ @RESTController.args_from_json
+ def bar(self, key, param=None):
+ return {'my_param': param, 'key': key}
+
class TaskControllerTest(ControllerTestCase):
@classmethod
def test_delete_task(self):
self._task_delete('/test/task/hello')
+
+ def test_foo_task(self):
+ self._task_post('/test/task/foo', {'param': 'hello'})
+ self.assertJsonBody({'my_param': 'hello'})
+
+ def test_bar_task(self):
+ self._task_put('/test/task/3/bar', {'param': 'hello'})
+ self.assertJsonBody({'my_param': 'hello', 'key': '3'})