I'm trying to find out how to receive JSON POST data in Python 2.7 with a cherrypy installation that serves both html and json
I'm using this script to send a demo JSON request
import urllib2
import json
def mytest():
d = {
'hello': '1',
'world': '2'
}
print(json.dumps(d))
URL = 'http://localhost:8092/json_in'
print(URL)
post_data = json.dumps(d)
req = urllib2.Request(URL, post_data)
RESULT = urllib2.urlopen(req).read()
print(RESULT)
if __name__ == '__main__':
mytest()
The cherrypy side works like this
# -*- coding: utf-8 -*-^
import cherrypy
class WelcomePage:
def index(self):
return "<html><body>hello world</body><html>"
index.exposed = True
def json_in(self,**kwargs):
print kwargs
# this is dumb but works to grab the first and only argument
for key,value in kwargs.iteritems():
myjson = key
parsed_json = json.loads(myjson)
print(parsed_json['hello'])
return "{}"
json_in.exposed = True
if __name__ == '__main__':
cherrypyconf = "cherrypy.conf"
cherrypy.quickstart(WelcomePage(),config=cherrypyconf)
When I start the server and send a request I can see my request in the consule (from the print command) but the string parse fails with the error TypeError: expected string or buffer
Any hint how to fix this?
UPDATE:
The problem seems that I didn't understand how to handle **kwargs. The updated code works (but uses a very dumb way to extract the JSON until I find the correct syntax to get the first argument)
You are not gaining advantage of some of the build in tools that cherrypy offers and the client code is not specifying the right content type.
The client code should looks like this: (notice the content type header):
import urllib2
import json
def mytest():
d = {
'hello': '1',
'world': '2'
}
print(json.dumps(d))
URL = 'http://localhost:8092/json_in'
print(URL)
post_data = json.dumps(d)
req = urllib2.Request(URL, post_data, headers={
'Content-Type': 'application/json'
})
RESULT = urllib2.urlopen(req).read()
print(RESULT)
if __name__ == '__main__':
mytest()
And your server code like this:
# -*- coding: utf-8 -*-
import cherrypy as cp
class WelcomePage:
@cp.expose
def index(self):
return "<html><body>hello world</body><html>"
@cp.expose
@cp.tools.json_in()
@cp.tools.json_out()
def json_in(self):
print(cp.request.json['hello'])
return {}
if __name__ == '__main__':
cherrypyconf = "cherrypy.conf"
cp.quickstart(WelcomePage(),config=cherrypyconf)