Package: tornadorpc
[![Build Status](https://travis-ci.org/joshmarshall/tornadorpc.png?branch=master)](https://travis-ci.org/joshmarshall/tornadorpc)TORNADO-RPC===========This library is an implementation of both the JSON-RPC and theXML-RPC specification (server-side) for the Tornado web framework.It supports the basic features of both, as well as the MultiCall /Batch support for both specifications. The JSON-RPC handler supportsboth the original 1.0 specification, as well as the new (proposed)2.0 spec, which includes batch submission, keyword arguments, etc.Asynchronous request support has been added for methods which requirethe use of asynchronous libraries (like Tornado's AsyncHTTPClientlibrary.)TornadoRPC is licensed under the Apache License, Version 2.0(http://www.apache.org/licenses/LICENSE-2.0.html).Mailing List------------If you have any questions, issues, or just use the library please feelfree to send a message to the mailing list at:http://groups.google.com/group/tornadorpcInstallation------------To install:python setup.py buildsudo python setup.py installTo use this module, you'll need Tornado installed, which you canget at this address:http://www.tornadoweb.org/If you want to use the JSON-RPC handler, you'll also needjsonrpclib, which you can grab at:http://github.com/joshmarshall/jsonrpclib/The jsonrpclib library requires one of the JSON libraries. It looksfirst for cjson, then for the built-in JSON library (with defaultPython 2.6+ distributions), and finally the simplejson library.Overview--------This library is an implementation of both the JSON-RPC and the XML-RPCspecification (server-side) for the Tornado web framework. It supportsthe basic features of both, as well as the MultiCall / Batch support forboth specifications. The JSON-RPC handler supports both the original 1.0specification, as well as the new (proposed) 2.0 spec, which includes batchsubmission, keyword arguments, etc.There is also a base library that other RPC protocols could use to quicklyget tied into Tornado.Requirements------------The library obviously requires Tornado, which you can get atTornado's website (http://www.tornadoweb.org). After installing Tornado(instructions included with the Tornado distribution) you should be ableto use the XML-RPC handler without any other libraries.The JSON-RPC handler requires my jsonrpclib library, which you can getat http://github.com/joshmarshall/jsonrpclib . It also requires a JSONlibrary, although any distribution of Python past 2.5 should have it bydefault. (Note: Some Linuxes only include a base Python install. On Ubuntu,for instance, you may need to run `sudo apt-get install python-json` or`sudo apt-get python-cjson` to get one of the libraries.)Usage-----The library is designed to be mostly transparent in usage. You simplyextend the XML/JSON RPCHandler class from either the tornadorpc.xml orthe tornado.json library, resepectively, and pass that handler in tothe Tornado framework just like any other handler.For any synchronous (normal) operation, you can just return the valueyou want sent to the client. However, if you use any asynchronouslibrary (like Tornado's AsyncHTTPClient) you will want to callself.result(RESULT) in your callback. See the Asynchronous sectionbelow for examples.XML-RPC Example---------------To set up a simple XML RPC server, this is all you need:from tornadorpc.xml import XMLRPCHandlerfrom tornadorpc import private, start_serverclass Handler(XMLRPCHandler):def add(self, x, y):return x+ydef ping(self, obj):return obj@privatedef private(self):#should not get calledreturn Falsestart_server(Handler, port=8080)The `@private` decorator is a way to ensure that it cannot be calledexternally. You can also create methods that start with an underscore `_`character, and they will be private by default. The `start_server` functionis just an easy wrap around the default Tornado setup -- you can use thesehandlers just like you would any other Tornado RequestHandler.JSON-RPC Example----------------A JSON-RPC server would be started with the exact same syntax, replacingXMLRPCHandler with JSONRPCHandler. Here is an example of the JSON-RPCclient with "dot-attribute" support:from tornadorpc.json import JSONRPCHandlerfrom tornadorpc import private, start_serverclass Tree(object):def power(self, base, power, modulo=None):result = pow(base, power, modulo)return resultdef _private(self):# Won't be callablereturn Falseclass Handler(JSONRPCHandler):tree = Tree()def add(self, x, y):return x+ydef ping(self, obj):return objstart_server(Handler, port=8080)To use this, you should be able to use either the JSON-RPC officialimplementation, or the jsonrpclib library (which you'd need for this towork anyway.) One of the benefits of the jsonrpclib is designed to be aparallel implementation to the xmlrpclib, so syntax should be very similarand it should be easy to experiment with existing apps.An example of client usage would be:from jsonrpclib import Serverserver = Server('http://localhost:8080')result = server.tree.power(2, 6)# result should equal 64Asynchronous Example--------------------To indicate that a request is asynchronous, simply use the "async"decorator, and call "self.result(RESULT)" in your callback. Please notethat this will only work in the RPCHandler methods, not in any sub-treemethods since they do not have access to the handler's result() method.Here is an example that uses Tornado's AsyncHTTPClient with a callback:from tornadorpc import asyncfrom tornadorpc.xml import XMLRPCHandlerfrom tornado.httpclient import AsyncHTTPClientclass Handler(XMLRPCHandler):@asyncdef external(self, url):client = AsyncHTTPClient()client.fetch(url, self._handle_response)def _handle_response(self, response):# The underscore will make it private automatically# You could also use @private if you wished# This returns the status code of the requestself.result(response.code)Debugging---------There is a `config` object that is available -- it will be expanded as timegoes by. Currently, it supports two options: `verbose` and `short_errors`,both of which default to True. The `verbose` setting just specifies whetheryou want to print out results to the terminal (automatically on, you'llprobably want to turn that off for production, WSGI deployment, etc.) andthe `short_errors` option determines whether to print just the last fewlines of the traceback (if set to True, default) or print the full traceback.Once the logging mechanism is in place, the `short_errors` configurationelement will apply to that as well.The default error look something similar to this:JSON-RPC SERVER AT http://localhost:8484---------------ERROR IN messup---------------Traceback (most recent call last):File "test.py", line 20, in messupreturn doesntexist['bad_key']NameError: global name 'doesntexist' is not definedTo change the configuration, look over the following:import tornadorpctornadorpc.config.verbose = Falsetornadorpc.config.short_errors = False# or...from tornadorpc import configconfig.verbose = Falseconfig.short_errors = FalseTests-----To run some basic tests, enter the following in the same directory thatthis README is in:python run_tests.pyThis will test a few basic utilites and the XMLRPC system. If you wishto test the JSONRPC system, run the following:python run_tests.py --jsonTODO----* Add unit tests* Add logging mechanism* Add proper HTTP codes for failures* Optimize