views:

112

answers:

1

When I send a POST message to the GAE with a json parameters using POST the QueryDict parsed by the server is not parsed like a json ...

I found a similar problem in this issue: http://stackoverflow.com/questions/2579235/iphone-json-post-request-to-django-server-creates-querydict-within-querydict

Maybe is a problem with the GAE configuration. I've Python 2.6.6 with the last version of GAE. First of all, If I get the POST with a nc tool, the POST message is perfect:

POST /url/ HTTP/1.1
Accept: application/jsonrequest
Content-type: application/json
Accept-Encoding: gzip
Content-Length: 458
Host: 192.168.1.1:8080
Connection: Keep-Alive

{"id":"xxx","jsonrpc":"2.0","method":"XXX","params":{...}]}

And in the server console I receive the next messages:

DEBUG    2010-09-16 06:47:05,891 dev_appserver.py:1693] Access to module file denied: /usr/lib/pymodules/python2.6/simplejson
DEBUG    2010-09-16 06:47:05,894 dev_appserver.py:1700] Could not import "_json": Disallowed C-extension or built-in module
DEBUG    2010-09-16 06:47:05,897 dev_appserver.py:1700] Could not import "_json": Disallowed C-extension or built-in module

And idea ¿?

The query dict in the server is <QueryDict: {u'{"id":"xxx","jsonrpc":"2.0","method":"XXX","params":{...}}': [u'']}>

As you can check the django handler parse the json of the POST request as a key of a new dictionary ...

In the linked issue there's the next solution ...

hack_json_value = request.POST.keys()[0]
hack_query_dict = json.loads(hack_json_value)
foo = hack_query_dict['foo']
bar = hack_query_dict['bar']

but maybe you can help me to find another one ...

Thanks,

+2  A: 

The first thing you need to remember when working with json is that AppEngine lives with python 2.5. This means json is not a standard part of python yet.

To solve that bit I found simplejson somewhere online and packed it together with my code. The API for built-in json and simplejson are essentially the same (or maybe I've just not noticed anything different) so just import it like so:

import simplejson as json

And use it like you're used to.

Now, as for the QueryDict. Yes, what you're getting through is raw POST data, there is no logical reason for it to get parsed as json and play pretend that it's a normal query-based POST request. Honestly, I never thought django was even able of making this leap of judgement for us. So, to get to your data use something along these lines:

data = json.loads(request.raw_post_data)

For reference of what django was expecting to see in the raw POST data check here: http://en.wikipedia.org/wiki/POST_(HTTP), specifically the bit about how application/x-www-form-urlencoded works.

Swizec Teller
Actually you don't have to upload simplejson with your code. It's accessible directly on App Engine via : from django.utils import simplejson
Franck
There is also an answer to another question providing the same solution : http://stackoverflow.com/questions/1208067/wheres-my-json-data-in-my-incoming-django-request/3244765#3244765
Franck
Yes sorry I'm already using simplejson. Btw this method simplejson.loads(request.raw_post_data) works perfectly. Thanks!!!
Iván Peralta
Really? Thanks Franck, had no idea it was already available :)
Swizec Teller