16

I'm trying to post a JSON object through a POST. I'm trying to do it as follows:

import json, urllib, urllib2

filename = 'test.json'
race_id = 2530
f = open(filename, 'r')
fdata = json.loads(f.read())
f.close()

prefix = 'localhost:8000'

count = 0
for points in fdata['positions'].iteritems():
    print '--' + str(count) + '--------'
    url = 'http://'+prefix+'/api/points'
    parameters = {'point_data': json.dumps(points), 'race_id': race_id}
    data = urllib.urlencode(parameters)
    print data
    request = urllib2.Request(url, data)
    response = urllib2.urlopen(request)
    count += 1
    break;

print 'Finished adding points'

The data is then received on the other end (I'm using Google App Engine) with:

point_data = json.load(self.request.get('point_data'))

But I get the following error:

ERROR    2010-06-30 15:08:05,367
__init__.py:391] 'unicode' object has no attribute 'read' Traceback (most
recent call last):   File
"/home/ian/workspace/google_appengine/google/appengine/ext/webapp/__init__.py",
line 513, in __call__
    handler.post(*groups)   File "/home/ian/workspace/codebase/track_builder/geo-api.py",
line 276, in post
    point_data = json.load(self.request.get('point_data'))
File
"/home/ian/workspace/google_appengine/lib/django/django/utils/simplejson/__init__.py",
line 208, in load
    return cls(encoding=encoding, **kw).decode(fp.read()) AttributeError: 'unicode' object has
no attribute 'read' INFO    
2010-06-30 15:08:05,376
dev_appserver.py:3266] "POST
/api/points HTTP/1.1" 500 -

Any ideas on how to fix this?

EDIT: As requested here is an example of the points:

(u'1276859700',
{
    u'24': {
        u'tempc': u'-22.7',
        u'gpsq': u'1',
        u'altm': u'65527',
        u'hd': u'112',
        u'hdop': u'0.93',
        u'bton': u'0',
        u'maxv': u'20.15',
        u'idit': u'1',
        u'satc': u'10',
        u'minv': u'20.15',
        u'lat': u'35.271993',
        u'btusr': u'0',
        u'lng': u'-121.845353',
        u'knots': u'7'
    },
    u'11': {
        u'tempc': u'13.0',
        u'gpsq': u'1',
        u'altm': u'65535',
        u'hd': u'130',
        u'hdop': u'0.84',
        u'bton': u'0',
        u'maxv': u'15.96',
        u'idit': u'1',
        u'satc': u'12',
        u'minv': u'15.88',
        u'lat': u'34.877815',
        u'btusr': u'0',
        u'lng': u'-121.386116',
        u'knots': u'8'
    }
}

EDIT 2: Thanks to Daniel Roseman and Nick Johnson who both caught my error. I've changed

point_data = json.loads(self.request.get('point_data'))

This has solved the error but, now I'm getting:

ERROR    2010-06-30 16:07:29,807 __init__.py:391] 'list' object has no attribute 'iteritems'
Traceback (most recent call last):
  File "/home/ian/workspace/google_appengine/google/appengine/ext/webapp/__init__.py", line 513, in __call__
    handler.post(*groups)
  File "/home/ian/workspace/codebase/track_builder/geo-api.py", line 255, in post
    for time, units in point_data.iteritems():
AttributeError: 'list' object has no attribute 'iteritems'
INFO     2010-06-30 16:07:29,816 dev_appserver.py:3266] "POST /api/points HTTP/1.1" 500 -

which relates to the following code:

class TrackPoint(webapp.RequestHandler):
    def post(self):
        point_data = json.loads(self.request.get('point_data'))
        race_id = self.request.get('race_id')
        added = []
        failed = []
        for time, units in point_data.iteritems():
            for unit, data in units.iteritems():
                ...

Any ideas on this one?

2
  • Since you haven't provided the actual points object, it's impossible to tell what it was encoded as or why it can't be encoded. You might want to print the points object so we can see what it is. Commented Jun 30, 2010 at 15:13
  • Can you re-paste the stacktrace as code, rather than a quote? SO's quoting has destroyed the original formatting, and it's nearly unreadable. Commented Jun 30, 2010 at 16:01

3 Answers 3

31

It looks like self.request.get() is returning a unicode object rather than a file-like object. You could try using json.loads() instead of json.load().

Sign up to request clarification or add additional context in comments.

2 Comments

That seemed to fix the problem. Now I'm getting "AttributeError: 'list' object has no attribute 'iteritems'". Any ideas on this one? I've appended the necessary code in my question above.
just for clarification, the actual error here was load tries to open the file then load the data, where as loads() is for text.
4

json.load() expects a file object, but self.request.get returns the value of the parameter as a string.

The solution is easy: use json.loads.

Also, free tip: I presume from the name that you're bundling your own copy of the json library. App Engine actually includes a copy of simplejson that you can use - just do:

from django.utils import simplejson

Comments

1

first in js I recognize that json object must in STRING format (javascript file)

// using jquery, json2
var js = {"name":"nguyen","age":"1"};
$.post("/", {'data': JSON.stringify(js)}, function(ret){
        alert(ret);
    });

then in gae

from django.utils import simplejson as json

class PesonReq(webapp.RequestHandler):
    def post(self):
        t = json.loads(self.request.POST['data'])
        self.response.out.write(t['name'])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.