2010-06-30 8 views
16

Ich versuche, ein JSON-Objekt über einen POST zu veröffentlichen. Ich versuche, es zu tun, wie folgt:Übergeben eines JSON-Objekts über POST mit Python

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' 

Die Daten wird dann am anderen Ende empfangen wird (ich bin mit Google App Engine) mit:

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

Aber ich bekomme die folgenden Fehler :

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 - 

Irgendwelche Ideen, wie man das behebt?

EDIT: Wie gewünscht hier ist ein Beispiel für die Punkte:

(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: Dank Daniel Roseman und Nick Johnson, die beide meine Fehler gefangen. Ich habe

geändert
point_data = json.loads(self.request.get('point_data')) 

Das den Fehler behoben hat, aber jetzt bin ich immer:

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 - 

, die auf den folgenden Code bezieht:

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(): 
       ... 

Irgendwelche Ideen auf diesem ?

+0

Da Sie das tatsächliche 'Punkte'-Objekt nicht angegeben haben, ist es unmöglich zu sagen, wofür es codiert wurde oder warum es nicht codiert werden kann. Vielleicht möchten Sie das Objekt "Punkte" drucken, damit wir sehen können, was es ist. –

+0

Können Sie den Stacktrace als Code anstatt als Zitat einfügen? SO's Zitat hat die ursprüngliche Formatierung zerstört, und es ist fast nicht lesbar. –

Antwort

31

Es sieht so aus, als ob self.request.get() ein Unicode-Objekt anstelle eines dateiähnlichen Objekts zurückgibt. Sie könnten versuchen, json.loads() anstelle von json.load() zu verwenden.

+0

Das schien das Problem zu beheben. Jetzt bekomme ich "AttributeError: 'list' Objekt hat kein Attribut 'iteritems'". Irgendwelche Ideen zu diesem? Ich habe den erforderlichen Code in meiner Frage oben angehängt. – blcArmadillo

+1

nur zur Klarstellung, der eigentliche Fehler hier war 'load' versucht, die Datei zu öffnen, dann laden Sie die Daten, wo als Lasten() für Text ist. –

4

json.load() erwartet ein Dateiobjekt, aber self.request.get gibt den Wert des Parameters als String zurück.

Die Lösung ist einfach: Verwenden Sie json.loads.

Auch, kostenloser Tipp: Ich vermute von dem Namen, dass Sie Ihre eigene Kopie der JSON-Bibliothek bündeln. App Engine enthält tatsächlich eine Kopie simplejson die Sie verwenden können - gerade tun:

from django.utils import simplejson 
1

zuerst in js ich erkenne, dass JSON-Objekt muss in STRING-Format (JavaScript-Datei)

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

dann 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']) 
Verwandte Themen