21

In my controller/request-handler, I have the following code:


def monkey(self, **kwargs):
  cherrypy.response.headers['Content-Type'] = "application/json"
  message = {"message" : "Hello World!" }
  return message
monkey.exposed = True

And, in my view, I've got this javascript:


$(function() {
  var body = document.getElementsByTagName("body")[0];
  $.ajaxSetup({ 
    scriptCharset : "utf-8",
    contentType: "application/json; charset=utf-8"
  });
  $.post("http://localhost/wsgi/raspberry/monkey", "somePostData",
    function(data) {
      try{
        var response = jQuery.parseJSON(data);
        body.innerHTML += "<span class='notify'>" + response + "</span>";
      }catch(e){ 
        body.innerHTML += "<span class='error'>" + e + "</span>";
      }
    }
  );
});

And finally, here's my problem. I get no JSON response and I'm not sure why.

Secondly, would someone be able to explain how to format data in my controller/request-handler response as a JSON response in the simplest way possible, without using tools?

bitcycle
  • 7,632
  • 16
  • 70
  • 121

2 Answers2

46

Since CherryPy 3.2 there are tools to accept/return JSON:

@cherrypy.expose
@cherrypy.tools.json_out()
def monkey(self, **params):
    return {"message": "Hello World!"}

Using json_out serializes the output and sets the appropriate Content-Type header for you.

Similarly decorating with @cherrypy.tools.json_in() can automatically accept/decode JSON post requests.

wim
  • 338,267
  • 99
  • 616
  • 750
fumanchu
  • 14,419
  • 6
  • 31
  • 36
  • Thanks for this. In reading Alex's post above and doing some testing on my own, I realize that your suggestion is more succinct, explicit, and readable than using JSON.dumps(). – bitcycle Sep 05 '10 at 22:37
  • CherryPy 3.2 has been released, by the way :) – fumanchu May 15 '11 at 23:45
  • Here's the documentation for json_out: http://docs.cherrypy.org/en/latest/refman/lib/jsontools.html?#cherrypy.lib.jsontools.json_out – Eric Smith Feb 26 '14 at 18:52
  • The above documentation is now at http://cherrypy.readthedocs.org/en/latest/pkg/cherrypy.lib.html?highlight=json_out#cherrypy.lib.jsontools.json_out – shr Aug 14 '15 at 07:31
14

Not sure what you mean by "without using tools" -- Python is "a tool", right?

With just Python and its standard library (2.6 or better), add at the top of your module

import json

and change the return statement to

return json.dumps(message)
Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • In Python 2.5, you can use the [simplejson](http://pypi.python.org/pypi/simplejson/) package. – detly Sep 04 '10 at 05:24
  • Actually, what I meant by saying "without tools" was without using decorators. I'm still getting used to python's idiosyncrasies. Yes, I have seen simplejson used, but I want to be able to do it using the base libraries first. – bitcycle Sep 04 '10 at 06:29
  • 1
    @Sean, `simplejson` is just the older version of `json`, from before the latter was incorporated into the Python standard library. IOW, `json` is not any more "base" than `simplejson`, it's just a "packaging" decision by the PSF (specifically by the core developers of Python itself and the standard library that goes with it). – Alex Martelli Sep 04 '10 at 14:34
  • 6
    "Tool" is CherryPy jargon for "plugin". There's a whole subsystem for using them and making your own: http://docs.cherrypy.org/dev/intro/concepts/tools.html – fumanchu Sep 06 '10 at 01:16
  • 1
    with this approach, you need to call `cherrypy.response.headers['Content-Type'] = 'application/json'` to set the correct content type. however you shoul rather use `@cherrypy.tools.json_out()` instead – dannymo Oct 16 '18 at 15:19