Recipe 15.2. Serving XML-RPC RequestsCredit: Brian Quinlan ProblemYou need to implement an XML-RPC server. SolutionModule 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.py 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( ) And here is a client script that accesses the server you just wrote: # 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 DiscussionThis 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 AlsoThe 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. |