Recipe 15.2. Serving XML-RPC Requests
Credit: Brian Quinlan
Problem
You need to implement an XML-RPC server.
Solution
Module SimpleXMLRPCServer, which is part of the
Python Standard Library, makes writing XML-RPC servers reasonably
easy. Here's how you can write an XML-RPC server:
# Server code sxr_server.pyAnd here is a client script that accesses the server you just wrote:
import SimpleXMLRPCServer
class StringFunctions(object):
def _ _init_ _(self):
# Make all the functions in Python's standard string module
# available as 'python_string.func_name' for each func_name
import string
self.python_string = string
def _privateFunction(self):
# This function cannot be called directly through XML-RPC because
# it starts with an underscore character '_', i.e., it's "private"
return "you'll never get this result on the client"
def chop_in_half(self, astr):
return astr[:len(astr)/2]
def repeat(self, astr, times):
return astr * times
if _ _name_ _=='_ _main_ _':
server = SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", 8000))
server.register_instance(StringFunctions( ))
server.register_function(lambda astr: '_' + astr, '_string')
server.serve_forever( )
# Client code sxr_client.py
import xmlrpclib
server = xmlrpclib.Server('http://localhost:8000')
print server.chop_in_half('I am a confident guy')
# emits: I an a con
print server.repeat('Repetition is the key to learning!\n', 5)
# emits 5 lines, all Repetition is the key to learning!
print server._string('<= underscore')
# emits _<= underscore
print server.python_string.join(['I', 'like it!'], " don't ")
# emits I don't like it!
print server._privateFunction( ) # this will throw an exception
# terminates client script with traceback for xmlrpclib.Fault
Discussion
This recipe demonstrates the creation of a simple XML-RPC server
using the SimpleXMLRPCServer module of the
standard Python library. The module contains a class of the same name
that listens for HTTP requests on a specified port and dispatches any
XML-RPC calls to registered instances or registered functions. This
recipe demonstrates both usages. To create a server, we instantiate
the SimpleXMLRPCServer class, supplying the
hostname and port for the server. Then, on that instance, we call
register_instance as many times as needed to make
other instances available as services. In addition, or as an
alternative, we call register_function to make
functions similarly available as services. Once we have registered
all the instances and/or all the functions we want to expose, we call
the serve_forever method of the server instance,
and our XML-RPC server is active. Yes, it is really that simple. The
only output on the shell prompt window on which you run the server is
one line of log information each time a client accesses the server;
the only way to terminate the server is to send it an interrupt, for
example with a Ctrl-C keystroke.Registering functions (as opposed to an instance) is necessary when a
function name begins with an underscore (_) or
contains characters not allowed in Python identifiers (e.g., accented
letters, punctuation marks, etc.). Dotted names (e.g.,
python_string.join) are correctly resolved for
registered instances.
See Also
The SimpleXMLRPCServer module is part of the
Python Standard Library and is documented in its chapter of the
Library Reference portion of
Python's online documentation.