Welcome, guest | Sign In | My Account | Store | Cart

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.

Python, 64 lines
 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 ]

3 comments

Olivier Dagenais 23 years ago  # | flag

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

skip 22 years, 10 months ago  # | flag

Example without using Medusa. The xmlrpclib module comes with both same client and server programs that don't require Medusa.

a 13 years, 11 months ago  # | flag

apply() is deprecated. apply(self.add, params) should be changed to self.add(*params)