Recipe15.3.Using XML-RPC with Medusa


Recipe 15.3. Using XML-RPC with Medusa

Credit: Jeff Bauer

Problem

You need to establish a lightweight, highly scalable, distributed processing system and want to use the XML-RPC protocol.

Solution

Package medusa lets you implement lightweight, highly scalable, asynchronous (event-driven) network servers. An XML-RPC handler is included in the Medusa distribution. Here is how you can code an XML-RPC server with Medusa:

# xmlrpc_server.py from socket import gethostname from medusa.xmlrpc_handler import xmlrpc_handler from medusa.http_server import http_server from medusa import asyncore class xmlrpc_server(xmlrpc_handler):     # initialize and run the server     def _ _init_ _(self, host=None, port=8182):         if host is None:             host = gethostname( )         hs = http_server(host, port)         hs.install_handler(self)         asyncore.loop( )     # an example of a method to be exposed via the XML-RPC protocol     def add(self, op1, op2):         return op1 + op2     # the infrastructure ("plumbing") to expose methods     def call(self, method, params):         print "calling method: %s, params: %s" % (method, params)         if method == 'add':             return self.add(*params)         return "method not found: %s" % method if _ _name_ _ == '_ _main_ _':     server = xmlrpc_server( )

And here is a client script that accesses the server you just wrote:

# xmlrpc_client.py from socket import gethostname from xmlrpclib import Transport, dumps class xmlrpc_connection(object):     def _ _init_ _(self, host=None, port=8182):         if host is None:             host = gethostname( )         self.host = "%s:%s" % (host, port)         self.transport = Transport( )     def remote(self, method, params=( )):         """ Invoke the server with the given method name and parameters.             The return value is always a tuple. """         return self.transport.request(self.host, '/RPC2',                                       dumps(params, method)) if _ _name_ _ == '_ _main_ _':     connection = xmlrpc_connection( )     answer, = connection.remote("add", (40, 2))     print "The answer is:", answer

Discussion

This recipe demonstrates remote method calls between two machines (or two processes, even on the same machine) using the XML-RPC protocol and provides a complete example of working client/server code.

XML-RPC is one of the easiest ways to handle distributed processing tasks. There's no messing around with the low-level socket details, nor is it necessary to write an interface definition. The protocol is platform and language neutral. The XML-RPC specification can be found at http://www.xml-rpc.com and is well worth studying. It's nowhere as functionally rich as heavyweight stuff like CORBA, but, to compensate, it is much simpler!

To run this recipe's Solution, you must download the Medusa library from http://www.nightmare.com (the Python Standard Library includes the asyncore and asynchat modules, originally from Medusa, but not the other parts of Medusa required for this recipe). With Medusa, you implement an XML-RPC server by subclassing the xmlrpc_handler class and passing an instance of your class to the install_handler method of an instance of http_server. HTTP is the transport-level protocol used by the XML-RPC standard, and http_server handles all transport-level issues on your behalf. You need to provide only the handler part, by customizing xmlrpc_handler through subclassing and method overriding. Specifically, you must override the call method, which the Medusa framework calls on your instance with the name of the XML-RPC method being called, along with its parameters, as arguments. This is exactly what we do in this recipe, in which we expose a single XML-RPC method named add which accepts two numeric parameters and returns their sum as the method's result.

This recipe's XML-RPC client uses xmlrpclib in a more sophisticated way than Recipe 15.1, by accessing the TRansport class explicitly. In theory, this approach allows finer-grained control. However, this recipe does not exert that kind of control, and it's rarely required in XML-RPC clients that you actually deploy, anyway.

See Also

The xmlrpclib module is part of the Python Standard Library and is documented in a chapter of the Library Reference portion of Python's online documentation. Medusa is at http://www.nightmare.com.



Python Cookbook
Python Cookbook
ISBN: 0596007973
EAN: 2147483647
Year: 2004
Pages: 420

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net