Skip to content
This repository has been archived by the owner on Feb 10, 2023. It is now read-only.

Commit

Permalink
Merge pull request #6 from zopefoundation/json-params
Browse files Browse the repository at this point in the history
pass resource function arguments from JSON
  • Loading branch information
freddrake committed Jul 10, 2014
2 parents 42900cf + 50308f0 commit 9b9860d
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 9 deletions.
2 changes: 2 additions & 0 deletions bobo/README.txt
Expand Up @@ -22,6 +22,8 @@ To learn more. visit: http://bobo.digicool.com
Change History
==============

- Bobo will pass resource function arguments from data in JSON request bodies.

2.1.1 2014-07-06
----------------

Expand Down
29 changes: 21 additions & 8 deletions bobo/src/bobo.py
Expand Up @@ -1223,34 +1223,47 @@ def handle(*args, **route):

return handle

_no_jget = {}.get
def _make_caller(obj, paramsattr):
spec = getargspec(obj)
nargs = nrequired = len(spec.args)
if spec.defaults:
nrequired -= len(spec.defaults)
no_jget = _no_jget

# XXX maybe handle f(..., **kw)?

def bobo_apply(*pargs, **route):
request = pargs[-1]
pargs = pargs[:-1] # () or (self, )
params = getattr(request, paramsattr)
rget = route.get
pget = params.getall
jget = 0
kw = {}
for index in range(len(pargs), nargs):
name = spec.args[index]
if name == 'bobo_request':
kw[name] = request
continue

v = route.get(name)
v = rget(name)
if v is None:
v = params.getall(name)
if not v:
if index < nrequired:
raise MissingFormVariable(name)
continue
if len(v) == 1:
v = v[0]
v = pget(name)
if v:
if len(v) == 1:
v = v[0]
else:
if jget == 0:
if request.content_type == 'application/json':
jget = request.json.get
else:
jget = no_jget
v = jget(name, request)
if v is request:
if index < nrequired:
raise MissingFormVariable(name)
continue

kw[name] = v

Expand Down
28 changes: 27 additions & 1 deletion bobodoctestumentation/src/bobodoctestumentation/decorator.test
Expand Up @@ -197,7 +197,10 @@ We use resources by calling the result of calling bobo_response:
... if input:
... env['wsgi.input'] = io.BytesIO(input.encode("utf-8"))
... env['CONTENT_LENGTH'] = str(len(input))
... env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
... if input.startswith('{'):
... env['CONTENT_TYPE'] = 'application/json'
... else:
... env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
... env['REQUEST_METHOD'] = 'POST'
... request = webob.Request.blank(url, env, **kw)
... try:
Expand Down Expand Up @@ -394,6 +397,29 @@ The post decorator will *only* use form data:
>>> call_resource(foo, '/a/b', 'z=1')
Raised MissingFormVariable: y

Data can also be passed from JSON request data:

>>> @bobo.query('/')
... def foo(bobo_request, x, y, z=None):
... return "%s %r %r %r" % (type(bobo_request).__name__, x, y, z)

>>> call_resource(foo, '/', '{"x":1, "y":2, "z":3}')
BoboException:
{'body': 'Request 1 2 3',
'content_type': 'text/html; charset=UTF-8',
'headers': [],
'status': 200}

You can mix url parameters and json data:

>>> call_resource(foo, '/?x=1', '{"y":2, "z":3}')
BoboException:
{'body': "Request u'1' 2 3",
'content_type': 'text/html; charset=UTF-8',
'headers': [],
'status': 200}


Resources as methods
--------------------

Expand Down
11 changes: 11 additions & 0 deletions bobodoctestumentation/src/bobodoctestumentation/index.txt
Expand Up @@ -666,6 +666,10 @@ You can specify one or more methods when using the ``resource``,

>>> update_module('helloapp', src)

In addition, there are other decordators, ``get``, ``head``, ``put``,
``delete``, and ``options`` that define resources that accept the
corresponding HTTP methods.

If multiple resources (resource, query, or post) in a module or class
have the same route strings, the resource used will be selected based
on both the route and the methods allowed. (If multiple resources match
Expand Down Expand Up @@ -713,6 +717,13 @@ The ability to provide handlers for specific methods provides support
for the `REST architectural style
<http://en.wikipedia.org/wiki/Representational_State_Transfer>`_.

JSON Request Bodies
===================

If you use a JSON request body, with content type
``application/json``, defining a JSON object, bobo will pass
properties from the JSON body as resource function arguments.

.. _configuration:

Beyond the bobo development server
Expand Down

0 comments on commit 9b9860d

Please sign in to comment.