Enabling Web Services Using XML-RPC

XML-RPC is a system for making function calls through HTTP using XML message formats. XML-RPC is very different from the REST style of architecture; while both can be elegant solutions in the right hands, they have almost opposite design principles. Where REST invites you to think about the nature of the web and design your application accordingly, XML-RPC tries to make web services fit into the way most developers already think about programming: you call functions and get back results.

In XML-RPC, a function call is encoded as XML and sent to the server using an HTTP POST request. The server then replies with an XML document containing the result of the function call. Here's an example XML-RPC request, calling the function echo with the string argument 'cheese':


 POST /RPC2 HTTP/1.0

 Host: localhost

 Content-Type: text/xml

 Content-length: 190



 

 

 echo

 

 

 cheese

 

 

 

 

And here's the response sent back from the server:


 HTTP/1.1 200 OK

 Connection: close

 Content-Length: 158

 Content-Type: text/xml

 Date: Mon, 6 Jun 2005 12:55:00 GMT



 

 

 

 

 You said: cheese

 

 

 

 

The XML format is simple and uses a limited set of common data types. For more information on XML-RPC, see the book Programming Web Services with XML-RPC, by Simon St.Laurent, Joe Johnston, and Edd Dumbill (O'Reilly).

XML-RPC has the advantage of being extremely easy to learn and use. Its limited set of supported data types makes it easy to implement, so you can find XML-RPC modules for almost any programming language. The twisted.web package supports XML-RPC out of the box, making it very easy to support XML-RPC web services in your application.

5.3.1. How Do I Do That?

The twisted.web.xmlrpc.XMLRPC class is a subclass of twisted.web.resource.Resource that does just about all the work of handling XML-RPC. All you have to do is define methods beginning with xmlrpc_, and it will make them available as XML-RPC functions. The script in Example 5-3 imports the wiki.py Wiki server from Example 5-1 and adds an XML-RPC interface.

Example 5-3. xmlrpc_server.py


import wiki

from twisted.web import server, xmlrpc



class WikiXmlRpc(xmlrpc.XMLRPC):

 def _ _init_ _(self, wikiData):

 self.wikiData = wikiData



 def xmlrpc_hasPage(self, path):

 return self.wikiData.hasPage(path)



 def xmlrpc_listPages(self):

 return self.wikiData.listPages( )



 def xmlrpc_getPage(self, path):

 return self.wikiData.getPage(path)



 def xmlrpc_getRenderedPage(self, path):

 return self.wikiData.getRenderedPage(path)



 def xmlrpc_setPage(self, path, data):

 self.wikiData.setPage(path, data)

 # wikiData.setPage returns None, which has no xmlrpc

 # representation, so you have to return something else

 return path



if __name__ == "_ _main_ _":

 import sys

 from twisted.internet import reactor

 datafile = sys.argv[1]

 wikiData = wiki.WikiData(datafile)

 siteRoot = rest_wiki.RootResource(wikiData)

 siteRoot.putChild('RPC2', WikiXmlRpc(wikiData))

 reactor.listenTCP(8082, server.Site(siteRoot))

 reactor.run( )

Run xmlrpc_server.py with a single argument, the name of your Wiki data file:


 python xmlrpc_server.py

This command runs a web server on port 8082 that works just like wiki.py from Example 5-1, but with the addition of a resource providing XML-RPC access at /RPC2 (which is somewhat of a standard location for XML-RPC services).

You can test the XML-RPC interface using the xmlrpclib module in the Python standard library:


 $ python

 Python 2.4.1 (#2, Apr 14 2005, 09:13:52)

 [GCC 4.0.0 20050413 (prerelease) (Debian 4.0-0pre11)] on linux2

 Type "help", "copyright", "credits" or "license" for more information.

 >>> import xmlrpclib

 >>> wiki = xmlrpclib.ServerProxy('http://localhost:8082/RPC2')

 >>> wiki.listPages( )

 ['WikiHome', 'CurlTest', 'WgetTest', 'RestTest']

 >>> wiki.setPage('PythonXmlRpcTest', 'Creating this through XmlRpc!')

 'PythonXmlRpcTest'

 >>> wiki.getRenderedPage('PythonXmlRpcTest')

 "Creating this through <a href="XmlRpc">XmlRpc</a>!"

 >>> wiki.listPages( )

 ['WikiHome', 'CurlTest', 'WgetTest', 'PythonXmlRpcTest', 'RestTest']

 

5.3.2. How Does That Work?

The xmlrpc .XMLRPC class is a Resource designed to handle XML-RPC requests. When it receives a POST request, it parses the incoming XML to extract the name of the function being called and the arguments. Then it looks for a matching method with an xmlrpc_ prefix and calls it with the arguments provided by the client. This function can return a Deferred result or a direct value. The XMLRPC class encodes the result as XML and returns it to the client.

XML-RPC has a limited set of data types. You can return strings, integers, floating-point numbers, Booleans, dictionaries, tuples, or lists, and they will be converted automatically to their XML-RPC representations. To send a date value, wrap a date tuple such as the result of time.localtime( ) in an xmlrpc.DateTime object. To send binary data, wrap a binary string in an xmlrpc.Binary object. Other data types, including None, have no equivalent in XML-RPC. Attempting to return an unsupported data type will result in an error, so make sure that you limit your return values to the supported types.

Getting Started

Building Simple Clients and Servers

Web Clients

Web Servers

Web Services and RPC

Authentication

Mail Clients

Mail Servers

NNTP Clients and Servers

SSH

Services, Processes, and Logging



Twisted Network Programming Essentials
Twisted Network Programming Essentials
ISBN: 0596100329
EAN: 2147483647
Year: 2004
Pages: 107
Authors: Abe Fettig

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