Chris McDonough
2011-07-10 6a0602b3ce4d2a6de9dca25d8e0d390796a79267
request.json -> request.json_body; add some docs for json_body
7 files modified
116 ■■■■ changed files
CHANGES.txt 13 ●●●●● patch | view | raw | blame | history
docs/api/request.rst 10 ●●●● patch | view | raw | blame | history
docs/glossary.rst 3 ●●●●● patch | view | raw | blame | history
docs/narr/webob.rst 55 ●●●●● patch | view | raw | blame | history
docs/whatsnew-1.1.rst 7 ●●●●● patch | view | raw | blame | history
pyramid/request.py 5 ●●●●● patch | view | raw | blame | history
pyramid/tests/test_request.py 23 ●●●●● patch | view | raw | blame | history
CHANGES.txt
@@ -9,10 +9,9 @@
  object created by Pyramid.  (See the Venusian documentation for more
  information about ``Scanner``).
- New request attribute: ``json``. If the request's ``content_type`` is
  ``application/json``, this attribute will contain the JSON-decoded
  variant of the request body.  If the request's ``content_type`` is not
  ``application/json``, this attribute will be ``None``.
- New request property: ``json_body``. This property will return the
  JSON-decoded variant of the request body.  If the request body is not
  well-formed JSON, this property will raise an exception.
- A new value ``http_cache`` can be used as a view configuration
  parameter.
@@ -73,6 +72,12 @@
  IResponse.  It wasn't always, because the response was resolved by the
  router instead of early in the view wrapping process.  This has been fixed.
Documentation
-------------
- Added a section in the "Webob" chapter named "Dealing With A JSON-Encoded
  Request Body" (usage of ``request.json_body``).
1.1a4 (2011-07-01)
==================
docs/api/request.rst
@@ -180,12 +180,12 @@
      object (exposed to view code as ``request.response``) to influence
      rendered response behavior.
   .. attribute:: json
   .. attribute:: json_body
      If the request's ``content_type`` is ``application/json``, this
      attribute will contain the JSON-decoded variant of the request body.
      If the request's ``content_type`` is not ``application/json``, this
      attribute will be ``None``.
       This property will return the JSON-decoded variant of the request
       body.  If the request body is not well-formed JSON, or there is no
       body associated with this request, this property will raise an
       exception.  See also :ref:`request_json_body`.
.. note::
docs/glossary.rst
@@ -506,6 +506,9 @@
     `JavaScript Object Notation <http://www.json.org/>`_ is a data
     serialization format.
   jQuery
     A popular `Javascript library <http://jquery.org>`_.
   renderer
     A serializer that can be referred to via :term:`view
     configuration` which converts a non-:term:`Response` return
docs/narr/webob.rst
@@ -78,6 +78,10 @@
    ``PUT``.  You can also get ``req.body_file`` for a file-like
    object.
``req.json_body``
    The JSON-decoded contents of the body of the request. See
    :ref:`request_json_body`.
``req.cookies``:
    A simple dictionary of all the cookies.
@@ -239,6 +243,57 @@
API documentation for a multidict exists as
:class:`pyramid.interfaces.IMultiDict`.
.. _request_json_body:
Dealing With A JSON-Encoded Request Body
++++++++++++++++++++++++++++++++++++++++
.. note:: this feature is new as of Pyramid 1.1.
:attr:`pyramid.request.Request.json_body` is a property that returns a
:term:`JSON` -decoded representation of the request body.  If the request
does not have a body, or the body is not a properly JSON-encoded value, an
exception will be raised when this attribute is accessed.
This attribute is useful when you invoke a Pyramid view callable via
e.g. jQuery's ``$.post`` or ``$.ajax`` functions, which have the potential to
send a JSON-encoded body or parameters.
Using ``request.json_body`` is equivalent to:
.. code-block:: python
   from json import loads
   loads(request.body, encoding=request.charset)
Here's how to construct an AJAX request in Javascript using :term:`jQuery`
that allows you to use the ``request.json_body`` attribute when the request
is sent to a Pyramid application:
.. code-block:: javascript
    jQuery.ajax({type:'POST',
                 url: 'http://localhost:6543/', // the pyramid server
                 data: JSON.stringify({'a':1}),
                 contentType: 'application/json; charset=utf-8',
                 dataType: 'json'});
When such a request reaches a view in your application, the
``request.json_body`` attribute will be available in the view callable body.
.. code-block:: javascript
    @view_config(renderer='json')
    def aview(request):
        print request.json_body
        return {'result':'OK'}
For the above view, printed to the console will be:
.. code-block:: python
    {u'a': 1}
More Details
++++++++++++
docs/whatsnew-1.1.rst
@@ -99,10 +99,9 @@
  the Venusian ``Scanner`` object created by Pyramid.  (See the
  :term:`Venusian` documentation for more information about ``Scanner``).
- New request attribute: ``json``. If the request's ``content_type`` is
  ``application/json``, this attribute will contain the JSON-decoded
  variant of the request body.  If the request's ``content_type`` is not
  ``application/json``, this attribute will be ``None``.
- New request property: ``json_body``. This property will return the
  JSON-decoded variant of the request body.  If the request body is not
  well-formed JSON, this property will raise an exception.
- A new value ``http_cache`` can be used as a :term:`view configuration`
  parameter.
pyramid/request.py
@@ -491,9 +491,8 @@
        return adapted is ob
    @property
    def json(self):
        if self.content_type == 'application/json':
            return json.loads(self.body, encoding=self.charset)
    def json_body(self):
        return json.loads(self.body, encoding=self.charset)
def route_request_iface(name, bases=()):
pyramid/tests/test_request.py
@@ -233,25 +233,28 @@
        request.registry.registerAdapter(adapter, (Foo,), IResponse)
        self.assertEqual(request.is_response(foo), True)
    def test_json_incorrect_mimetype(self):
        request = self._makeOne({})
        self.assertEqual(request.json, None)
    def test_json_correct_mimetype(self):
    def test_json_body_invalid_json(self):
        request = self._makeOne({'REQUEST_METHOD':'POST'})
        request.content_type = 'application/json'
        request.body = '{'
        self.assertRaises(ValueError, getattr, request, 'json_body')
    def test_json_body_valid_json(self):
        request = self._makeOne({'REQUEST_METHOD':'POST'})
        request.body = '{"a":1}'
        self.assertEqual(request.json, {'a':1})
        self.assertEqual(request.json_body, {'a':1})
    def test_json_alternate_charset(self):
    def test_json_body_alternate_charset(self):
        from pyramid.compat import json
        request = self._makeOne({'REQUEST_METHOD':'POST'})
        request.content_type = 'application/json'
        request.charset = 'latin-1'
        la = unicode('La Pe\xc3\xb1a', 'utf-8')
        body = json.dumps({'a':la}, encoding='latin-1')
        request.body = body
        self.assertEqual(request.json, {'a':la})
        self.assertEqual(request.json_body, {'a':la})
    def test_json_body_GET_request(self):
        request = self._makeOne({'REQUEST_METHOD':'GET'})
        self.assertRaises(ValueError, getattr, request, 'json_body')
class TestRequestDeprecatedMethods(unittest.TestCase):
    def setUp(self):