Howto: pyjamas + pylons + json
I’ve been playing with the excellent pyjamas and I thought i’d share my experiences of using pylons to create a simple json service for the pyjamas client.
The idea is simple. Pyjamas can create rich ajax applications in the same style as GWT but in python rather than Java. However, it leaves the implementation of the server side up to you. The aim of this entry is to show how easy it is to use pylons to provide a json based service for the client.
First, you need to make sure you’ve got pylons and pyjamas installed, which you can do with easy_install. Next, create the template using paster, and start the server.
/tmp$paster create --template pylons echo .... /tmp$ cd echo/ /tmp/echo$ paster serve --reload development.ini Starting subprocess with file monitor Starting server in PID 6377. serving on 0.0.0.0:5000
Now, point your browser at http://localhost:5000/ and you should see the default pylons page. To get the client side working. We need to copy the json pyjamas example into the public directory (this contains static files to be served). Then edit build.sh to point to your pyjamas installation build script.
/tmp/echo$ cd echo/public/ /tmp/echo/echo/public$ cp -r /.../pyjamas/examples/jsonrpc/* . /tmp/echo/echo/public$ echo "python2.4 /.../pyjamas/builder/build.py JSONRPCExample.py" > build.sh james@jlap:/tmp/echo/echo/public$ ./build.sh Building 'JSONRPCExample.py' to output directory 'output' ...
If you now point your browser at http://localhost:5000/output/JSONRPCExample.html you should be able to see the example. I recommend that you install the mozilla live http headers plugin. This allows you to see what resources the client is interacting with. If you press “send to python service”, you will see a POST to output/services/EchoService.py. Edit JSONRPCExample.py so that the EchoServicePython class looks like this:
class EchoServicePython(JSONProxy): def __init__(self): JSONProxy.__init__(self, "/echoservice/json", ["echo", "reverse", "uppercase", "lowercase"])
You now need to rebuild the client with build.sh and restart the server. Unfortunately, the paster server doesn’t reload automatically when changes are made to the public directory so you need to do this manually. We have now set the python rpc service to point at /echoservice/json. In pylons terms, this will be automatically mapped to a method named json on a controller called echoservice. Create a file called echoservice.py in echo/controllers and put this in it.
from echo.lib.base import * class EchoserviceController(BaseController): def index(self): return Response('Echo World')
If you now visit http://localhost:5000/echoservice/index you should see “echo world” coming from that controller. Now all we need to add is the json part of the controller. Put this into echoservice.py
from echo.lib.base import * from pylons.decorators import jsonify import simplejson class EchoserviceController(BaseController): def index(self): return Response('Hello World') @jsonify def json(self): body = request.body.read(int(request.environ['CONTENT_LENGTH'])) json = simplejson.loads(body) data = json['params'][0] method = json['method'] if method == 'reverse': data = data[::-1] if method == 'uppercase': data = data.upper() if method == 'lowercase': data = data.lower() return dict(result=data)
Now try the “send to python service” and you should see the correct results returned. So what have we done here? Firstly, we needed to decode the method body. Import simplejson and use the loads method on the body got from the request object. The json object is a dict, so we can access the method name and parameters and create a dictionary with the answer stored under the result key. To return the data in json format, we just need the jsonify decorator which will translate the dictionary for us. Simple, huh?
When you mess up the service, it is worth knowing that you can inspect the stack using the debug url. This is given both in the console, and the http headers. Note also that storing the source python for the client in the public directory is stupid, but you knew that.
December 11th, 2006 at 5:33 pm I hope this can also be done using Windows, as I’ve wanted the JSON server. If it can, how?
December 12th, 2006 at 9:30 am I see no reason why paste/pylons won’t work on windows too, and the code should be exactly the same. What went wrong trying this approach?