2010-06-30 13 views
16

Sto tentando di pubblicare un oggetto JSON tramite un POST. Sto cercando di farlo nel modo seguente:Passaggio di un oggetto JSON tramite POST utilizzando 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' 

I dati vengono poi ricevuti sull'altra estremità (sto usando Google App Engine) con:

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

Ma ottengo il seguente errore :

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 - 

Qualche idea su come risolvere questo problema?

EDIT: Come richiesto ecco un esempio dei punti:

(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: grazie a Daniel Roseman e Nick Johnson che sia catturato il mio errore. Ho cambiato

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

Questo ha risolto l'errore, ma, ora sto ottenendo:

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 - 

che riguarda il codice seguente:

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

Tutte le idee su questo ?

+0

Dato che non è stato fornito l'oggetto 'punti', è impossibile stabilire cosa è stato codificato o perché non può essere codificato. Potresti voler stampare l'oggetto 'punti' in modo che possiamo vedere di cosa si tratta. –

+0

Riuscite a incollare lo stacktrace come codice, piuttosto che come una citazione? La citazione di SO ha distrutto la formattazione originale ed è quasi illeggibile. –

risposta

31

Sembra che self.request.get() restituisca un oggetto Unicode anziché un oggetto simile a un file. Potresti provare a utilizzare json.loads() anziché json.load().

+0

Sembrava risolvere il problema. Ora sto ricevendo "AttributeError: 'list' object non ha attributo 'iteritems'". Qualche idea su questo? Ho aggiunto il codice necessario nella mia domanda sopra. – blcArmadillo

+1

solo per chiarimenti, l'errore attuale era 'load' prova ad aprire il file e poi carica i dati, dove load() è per il testo. –

4

json.load() si aspetta un oggetto file, ma self.request.get restituisce il valore del parametro come una stringa.

La soluzione è semplice: utilizzare json.loads.

Inoltre, suggerimento gratuito: Presumo dal nome che si sta impacchettando la propria copia della libreria JSON. App Engine include in realtà una copia di simplejson che è possibile utilizzare - basta fare:

from django.utils import simplejson 
1

prima in js riconosco che oggetto JSON deve in formato STRING (file javascript)

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

poi nel 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']) 
Problemi correlati