This section demonstrates remote method calls between two machines (or processes) using the XML-RPC protocol. A complete example of working client/server code is provided.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | # 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):
"""The xmlrpc_server class demonstrates a simple implementation
of Userland's XML-RPC protocol. You must download and install
xmlrpclib and Medusa to run this code.
Obtain Sam Rushing's Medusa library from http://www.nightmare.com
Download Fredrik Lundh's xmlrpclib at http://www.pythonware.com"""
def __init__(self, host=None, port=8182):
if host is None:
host = gethostname()
hs = http_server(host, port)
hs.install_handler(self)
asyncore.loop()
def add(self, op1, op2):
return op1 + op2
def call(self, method, params):
print "call method: %s, params: %s" % (method, str(params))
if method == 'add':
return apply(self.add, params)
return "method not found: %s" % method
if __name__ == '__main__':
server = xmlrpc_server()
---
# xmlrpc_client.py
from socket import gethostname
from xmlrpclib import Transport, dumps
class xmlrpc_connection:
"""The xmlrpc_connection class tests the xmlrpc_server. You must
download and install the medusa and xmlrpclib libraries to run
this code: http://www.nightmare.com http://www.pythonware.com"""
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=()):
"""remote invokes the server with the method name and an
optional set of parameters. The return value is always a
tuple."""
response = self.transport.request(self.host,
'/RPC2',
dumps(params, method))
return response
if __name__ == '__main__':
connection = xmlrpc_connection()
(answer,) = connection.remote("add", (40, 2))
print "The answer is:", answer
|
XML-RPC is one of the easier 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-neutral and language-neutral. The XML-RPC specification can be found at: http://www.xml-rpc.com
To run the example above, it is necessary to download xmlrpclib from http://www.pythonware.com and the Medusa library from http://www.nightmare.com.
[ Aside: Perhaps someone from ActiveState can provide an additional client example in Perl, to demonstrate how multiple languages can be used together with xmlrpc. -Jeff ]
Without Medusa? I would very much like to see an implementation of XML-RPC that doesn't require Medusa. Maybe as a CGI or "threaded-long-running-web-process" program? (although then we're probably better off using SOAP) Olivier Dagenais
Example without using Medusa. The xmlrpclib module comes with both same client and server programs that don't require Medusa.
apply()
is deprecated.apply(self.add, params)
should be changed toself.add(*params)