Dalke Scientific Software: More science. Less time. Products
[ previous | newer ]     /home/writings/diary/archive/2006/10/24/xmlrpc_in_turbogears

XML-RPC in TurboGears

On-and-off I've looked for some way to get XML-RPC working in TurboGears. There's a CherryPy filter but I couldn't get it working. From what I've seen of the examples it makes all functions available to XML-RPC, which isn't something I wanted.

I finally gave up and rolled my own with xmlrpclib and using SimpleXMLRPCServer.py as a guide. It was simpler than trying to figure out the CherryPy mechanism, and simple enough that I'll list it here more as a recipe than a reusable module.

import sys
import xmlrpclib
import cherrypy
import turbogears
from turbogears import controllers

class RPCRoot(controllers.Controller):
    @turbogears.expose()
    def index(self):
        params, method = xmlrpclib.loads(cherrypy.request.body.read())
        try:
            if method == "index":
                # prevent recursion
                raise AssertionError("method cannot be 'index'")
            # Get the function and make sure it's exposed.
            method = getattr(self, method, None)
            # Use the same error message to hide private method names
            if method is None or not getattr(method, "exposed", False):
                raise AssertionError("method does not exist")

            # Call the method, convert it into a 1-element tuple
            # as expected by dumps                       
            response = method(*params)
            response = xmlrpclib.dumps((response,), methodresponse=1)
        except xmlrpclib.Fault, fault:
            # Can't marshal the result
            response = xmlrpclib.dumps(fault)
        except:
            # Some other error; send back some error info
            response = xmlrpclib.dumps(
                xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value))
                )

        cherrypy.response.headers["Content-Type"] = "text/xml"
        return response

    # User-defined functions must use cherrypy.expose; turbogears.expose
    # does additional checking of the response type.
    @cherrypy.expose
    def add(self, a, b):
        return a+b

class Root(controllers.RootController):
    RPC2 = RPCRoot()

Speaking of recipe, also tried to list it in the Python Cookbook but after several minutes waiting for the login to work I got the message "We are currently experiencing technical issues. Please try again shortly."



Copyright © 2001-2008 Dalke Scientific Software, LLC.