json post cherrypy

¿Cómo recibir JSON en una solicitud POST en CherryPy?



(3)

¿Cómo recibir JSON de las solicitudes POST en CherryPy?

He estado en esta página , y aunque hace un buen trabajo explicando la API, sus parámetros y lo que hace; Parece que no puedo descifrar cómo usarlos para analizar el JSON entrante en un objeto.

Esto es lo que tengo hasta ahora:

import cherrypy import json from web.models.card import card from web.models.session import getSession from web.controllers.error import formatEx, handle_error class CardRequestHandler(object): @cherrypy.expose def update(self, **jsonText): db = getSession() result = {"operation" : "update", "result" : "success" } try: u = json.loads(jsonText) c = db.query(card).filter(card.id == u.id) c.name = u.name c.content = u.content rzSession.commit() except: result["result"] = { "exception" : formatEx() } return json.dumps(result)

Y, aquí está mi llamada jquery para hacer la publicación

function Update(el){ el = jq(el); // makes sure that this is a jquery object var pc = el.parent().parent(); pc = ToJSON(pc); //$.ajaxSetup({ scriptCharset : "utf-8" }); $.post( "http://localhost/wsgi/raspberry/card/update", pc, function(data){ alert("Hello Update Response: " + data); }, "json"); } function ToJSON(h){ h = jq(h); return { "id" : h.attr("id"), "name" : h.get(0).innerText, "content" : h.find(".Content").get(0).innerText }; }


Pitón

import cherrypy class Root: @cherrypy.expose @cherrypy.tools.json_out() @cherrypy.tools.json_in() def my_route(self): result = {"operation": "request", "result": "success"} input_json = cherrypy.request.json value = input_json["my_key"] # Responses are serialized to JSON (because of the json_out decorator) return result

JavaScript

//assuming that you''re using jQuery var myObject = { "my_key": "my_value" }; $.ajax({ type: "POST", url: "my_route", data: JSON.stringify(myObject), contentType: ''application/json'', dataType: ''json'', error: function() { alert("error"); }, success: function() { alert("success"); } });


Ejemplo de trabajo:

import cherrypy import simplejson class Root(object): @cherrypy.expose def update(self): cl = cherrypy.request.headers[''Content-Length''] rawbody = cherrypy.request.body.read(int(cl)) body = simplejson.loads(rawbody) # do_something_with(body) return "Updated %r." % (body,) @cherrypy.expose def index(self): return """ <html> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> <script type=''text/javascript''> function Update() { $.ajax({ type: ''POST'', url: "update", contentType: "application/json", processData: false, data: $(''#updatebox'').val(), success: function(data) {alert(data);}, dataType: "text" }); } </script> <body> <input type=''textbox'' id=''updatebox'' value=''{}'' size=''20'' /> <input type=''submit'' value=''Update'' onClick=''Update(); return false'' /> </body> </html> """ cherrypy.quickstart(Root())

El documento al que vinculó describe un par de herramientas CherryPy que son nuevas en la versión 3.2. La herramienta json_in básicamente hace lo anterior, con algo más de rigor, y usa la nueva API de procesamiento de cuerpo en 3.2.

Una cosa importante a tener en cuenta es que la función de post de jQuery no parece poder enviar JSON (solo recibirlo). El argumento tipo de datos especifica el tipo de datos que espera que reciba XmlHTTPRequest, no el tipo que se enviará, y no parece haber un argumento disponible para que usted especifique el tipo que desea enviar. Usar ajax() cambio le permite especificar eso.


La forma @cherrypy.tools.json_in() me pareció no muy limpia ya que te obliga a utilizar cherrypy.request.json . En cambio, el siguiente decorador intenta imitar los parámetros GET .

Lo siguiente ayuda esto.

NOTA: Esto supone que desea devolver JSON:

def uses_json(func): @functools.wraps(func) @cherrypy.tools.accept(media="application/json") def wrapper(*args, **kwargs): cherrypy.serving.response.headers[''Content-Type''] = "application/json" kwargs = dict(kwargs) try: body = cherrypy.request.body.read() kwargs.update(json.loads(body)) except TypeError: pass return json.dumps(func(*args, **kwargs)).encode(''utf8'') return wrapper

ejemplo:

{"foo": "bar"}

get''s traducido a

@cherypy.expose @uses_json def endpoint(foo): ....