2013-03-20 10 views
6

Sto cercando di fare una richiesta put utilizzando un ASyncHTTPClient tornado in questo modo:Tornado PUT richiesta mancante corpo

data = { 'text': 'important text', 
      'timestamp': 'an iso timestamp' } 

    request = tornado.httpclient.HTTPRequest(URL, method = 'PUT', body = urllib.urlencode(data)) 

    response = yield Task(tornado.httpclient.ASyncHTTPClient().fetch, request) 

Tuttavia, quando la richiesta raggiunge il suo endpoint desiderato, sembra non avere un corpo, nonostante detto corpo essendo correttamente codificato e definito sopra. C'è qualcosa che sto trascurando qui?


+0

Da dove si importa 'HTTPRequest'? E anche come stai istanziando il 'client' – aychedee

+1

HTTPRequest proviene da tornado.httpclient, e il client è un alias per tornado.httpclient.ASyncHTTPClient. Aggiornerò la domanda per chiarire questo punto! –

+0

Non vedo niente di sbagliato con il codice che hai qui. Potrebbe essere un insetto sottile nel codice del gestore? – aychedee

risposta

4

Se l'altra estremità si aspetta JSON, probabilmente necessario impostare un header "Content-Type". Prova questo:

data = { 'text': 'important text', 
     'timestamp': 'an iso timestamp' } 

headers = {'Content-Type': 'application/json; charset=UTF-8'} 

request = tornado.httpclient.HTTPRequest(URL, method = 'PUT', headers = headers, body = simplejson.dumps(data)) 

response = yield Task(tornado.httpclient.ASyncHTTPClient().fetch, request) 

In questo modo, l'intestazione dice il server si sta inviando JSON, e il corpo è una stringa che può essere analizzato come JSON.

+1

Funziona, grazie mille! –

2

Il problema è probabilmente dall'altra parte.
Il seguente test utilizzando Tornado 2.4.1 fornisce l'output previsto.

import logging 
import urllib 

from tornado.ioloop import IOLoop 
from tornado.web import Application, RequestHandler, asynchronous 
from tornado.httpclient import HTTPRequest, AsyncHTTPClient 
from tornado import gen, options 

log = logging.getLogger() 
options.parse_command_line() 

class PutBodyTest(RequestHandler): 
    @asynchronous 
    @gen.engine 
    def get(self): 
     data = { 
      'text': 'important text', 
      'timestamp': 'a timestamp' 
     } 
     req = HTTPRequest(
      'http://localhost:8888/put_body_test', 
      method='PUT', 
      body=urllib.urlencode(data) 
     ) 
     res = yield gen.Task(AsyncHTTPClient().fetch, req) 
     self.finish() 

    def put(self): 
     log.debug(self.request.body) 

application = Application([ 
    (r"/put_body_test", PutBodyTest), 
]) 

if __name__ == "__main__": 
    application.listen(8888) 
    IOLoop.instance().start() 

uscita Log:

$ python put_test.py --logging=debug 
[D 130322 11:45:24 put_test:30] text=important+text&timestamp=a+timestamp 
[I 130322 11:45:24 web:1462] 200 PUT /put_body_test (127.0.0.1) 0.37ms 
[I 130322 11:45:24 web:1462] 200 GET /put_body_test (::1) 9.76ms 
+1

Grazie! Ho iniziato a sospettare simili, e l'esecuzione di questo test ha contribuito a confermarlo. –

0

questa è la richiesta di posta in attesa di JSON! Prova questo:

@gen.coroutine 
    def post(self): 
     http_client = AsyncHTTPClient() 
     http_client = tornado.httpclient.AsyncHTTPClient() 

     URL = "http://localhost:1338/api/getPositionScanByDateRange" 
     data = {"startDate":"2017-10-31 18:30:00","endDate":"2018-02-08 12:09:14","groupId":3} #A dictionary of your post data 
     headers = {'Content-Type': 'application/json; charset=UTF-8'} 

     record = yield http_client.fetch(URL, method = 'POST', headers = headers, body = json.dumps(data)) 

     if record.error: 
      response = record.error 
     else: 
      response = record.body 
     self.set_header('Content-Type', 'application/json') 
     self.finish(response) 
Problemi correlati