diff --git a/doc/changes.rst b/doc/changes.rst index a24b462..0b56886 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -4,8 +4,13 @@ Changes next ---- +* Add a special type 'HostRequest' that allow a function to ask for the host + framework request object in its arguments. + * New Flask adapter: wsmeext.flask +* Fix: the cornice adapter was not usable. + * Fix: Submodules of wsmeext were missing in the packages. * Fix: The demo app was still depending on the WSME-Soap package (which has diff --git a/tests/test_cornice.py b/tests/test_cornice.py index 19c93f1..9845a2b 100644 --- a/tests/test_cornice.py +++ b/tests/test_cornice.py @@ -6,7 +6,7 @@ import webtest from cornice import Service from pyramid.config import Configurator -from wsme.types import text, Base +from wsme.types import text, Base, HostRequest from wsmeext.cornice import signature @@ -30,6 +30,16 @@ def users_create(data): return data +needrequest = Service(name='needrequest', path='/needrequest') + + +@needrequest.get() +@signature(bool, HostRequest) +def needrequest_get(request): + assert request.path == '/needrequest', request.path + return True + + def make_app(): config = Configurator() config.include("cornice") @@ -77,3 +87,7 @@ class WSMECorniceTestCase(unittest.TestCase): resp.body, '2new' ) + + def test_pass_request(self): + resp = self.app.get('/needrequest') + assert resp.json is True diff --git a/wsme/api.py b/wsme/api.py index bfcb133..f51e2b5 100644 --- a/wsme/api.py +++ b/wsme/api.py @@ -4,6 +4,7 @@ import inspect import logging import wsme.exc +import wsme.types log = logging.getLogger(__name__) @@ -74,6 +75,11 @@ class FunctionDefinition(object): #: exceptions self.ignore_extra_args = False + #: name of the function argument to pass the host request object. + #: Should be set by using the :class:`wsme.types.HostRequest` type + #: in the function @\ :function:`signature` + self.pass_request = False + #: Dictionnary of protocol-specific options. self.extra_options = None @@ -122,8 +128,11 @@ class FunctionDefinition(object): default = None if not mandatory: default = defaults[i - (len(args) - len(defaults))] - self.arguments.append(FunctionArgument(argname, datatype, - mandatory, default)) + if datatype is wsme.types.HostRequest: + self.pass_request = argname + else: + self.arguments.append(FunctionArgument(argname, datatype, + mandatory, default)) class signature(object): diff --git a/wsme/types.py b/wsme/types.py index d336452..8836a35 100644 --- a/wsme/types.py +++ b/wsme/types.py @@ -180,6 +180,11 @@ class UnsetType(object): Unset = UnsetType() +#: A special type that corresponds to the host framework request object. +#: It can only be used in the function parameters, and if so the request object +#: of the host framework will be passed to the function. +HostRequest = object() + pod_types = six.integer_types + ( bytes, text, float, bool) diff --git a/wsmeext/cornice.py b/wsmeext/cornice.py index e03ed5e..53a4d4f 100644 --- a/wsmeext/cornice.py +++ b/wsmeext/cornice.py @@ -77,6 +77,8 @@ def signature(*args, **kwargs): args_from_body(funcdef, request.body, request.content_type)) ) request.override_renderer = 'wsme' + get_outputformat(request) + if funcdef.pass_request: + kwargs[funcdef.pass_request] = request return { 'datatype': funcdef.return_type, 'result': f(*args, **kwargs) diff --git a/wsmeext/flask.py b/wsmeext/flask.py index f840242..f9f5b79 100644 --- a/wsmeext/flask.py +++ b/wsmeext/flask.py @@ -55,6 +55,9 @@ def signature(*args, **kw): flask.request.mimetype ) + if funcdef.pass_request: + kwargs[funcdef.pass_request] = flask.request + dataformat = get_dataformat() try: diff --git a/wsmeext/pecan.py b/wsmeext/pecan.py index 06bb3ac..3fdb87f 100644 --- a/wsmeext/pecan.py +++ b/wsmeext/pecan.py @@ -65,6 +65,8 @@ def wsexpose(*args, **kwargs): funcdef, args, kwargs, pecan.request.params, None, pecan.request.body, pecan.request.content_type ) + if funcdef.pass_request: + kwargs[funcdef.pass_request] = pecan.request result = f(self, *args, **kwargs) except: data = wsme.api.format_exception(sys.exc_info()) diff --git a/wsmeext/tg1.py b/wsmeext/tg1.py index 3eb793a..70582d2 100644 --- a/wsmeext/tg1.py +++ b/wsmeext/tg1.py @@ -53,6 +53,8 @@ def wsexpose(*args, **kwargs): cherrypy.request.body, cherrypy.request.headers['Content-Type'] ) + if funcdef.pass_request: + kwargs[funcdef.pass_request] = cherrypy.request result = f(self, *args, **kwargs) return dict( datatype=funcdef.return_type,