Latest Version: 0.9.6.2
  Dashboard > Pylons Official Docs > Home > Using the XMLRPCController
  Pylons Official Docs Log In | Sign Up   View a printable version of the current page.  
  Using the XMLRPCController
Added by Graham Higgins, last edited by Philip Jenvey on Sep 09, 2007  (view change) show comment
Labels: 

Using the XMLRPCController for XML-RPC requests

In order to deploy this controller you will need at least a passing familiarity with XML-RPC itself. We will first review the basics of XML-RPC and then describe the workings of the Pylons XMLRPCController. Finally, we will show an example of how to use the controller to implement a simple web service.

After you've read this document, you may be interested in reading the companion document: "A blog publishing web service in XML-RPC" which takes the subject further, covering details of the MetaWeblog API (a popular XML-RPC service) and demonstrating how to construct some basic service methods to act as the core of a MetaWeblog blog publishing service.

A brief introduction to XML-RPC

XML-RPC is a specification that describes a Remote Procedure Call (RPC) interface by which an application can use the Internet to execute a specified procedure call on a remote XML-RPC server. The name of the procedure to be called and any required parameter values are "marshalled" into XML. The XML forms the body of a POST request which is despatched via HTTP to the XML-RPC server. At the server, the procedure is executed, the returned value(s) is/are marshalled into XML and despatched back to the application. XML-RPC is designed to be as simple as possible, while allowing complex data structures to be transmitted, processed and returned.

XML-RPC Controller that speaks WSGI

Pylons uses Python's xmlrpclib library to provide a specialised XMLRPCController class that gives you the full range of these XML-RPC Introspection facilities for use in your service methods and provides the foundation for constructing a set of specialised service methods that provide a useful web service — such as a blog publishing interface.

This controller handles XML-RPC responses and complies with the XML-RPC Specification as well as the XML-RPC Introspection specification.

As part of its basic functionality an XML-RPC server provides three standard introspection procedures or "service methods" as they are called. The Pylons XMLRPCController class provides these standard service methods ready-made for you:

  • system.listMethods Returns a list of XML-RPC methods for this XML-RPC resource
  • system.methodSignature Returns an array of arrays for the valid signatures for a method. The first value of each array is the return value of the method. The result is an array to indicate multiple signatures a method may be capable of.
  • system.methodHelp Returns the documentation for a method

By default, methods with names containing a dot are translated to use an underscore. For example, the system.methodHelp is handled by the method system_methodHelp.

Methods in the XML-RPC controller will be called with the method given in the XML-RPC body. Methods may be annotated with a signature attribute to declare the valid arguments and return types.

For example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class MyXML(XMLRPCController):
        def userstatus(self):
            return 'basic string'
        userstatus.signature = [ [docmeta:'string'] ]
        
        def userinfo(self, username, age=None):
            user = LookUpUser(username)
            response = {'username':user.name}
            if age and age > 10:
                response[docmeta:'age'] = age
            return response
        userinfo.signature = [ [docmeta:'struct', 'string'], [docmeta:'struct', 'string', 'int'] ]

Since XML-RPC methods can take different sets of data, each set of valid arguments is its own list. The first value in the list is the type of the return argument. The rest of the arguments are the types of the data that must be passed in.

In the last method in the example above, since the method can optionally take an integer value, both sets of valid parameter lists should be provided.

Valid types that can be checked in the signature and their corresponding Python types:

XMLRPC type Python type
string str
array list
boolean bool
int int
double float
struct dict
dateTime.iso8601 xmlrpclib.DateTime
base64 xmlrpclib.Binary

Note, requiring a signature is optional.

Also note that a convenient fault handler function is provided.

1
2
def xmlrpc_fault(code, message):
    """Convenience method to return a Pylons response XMLRPC Fault"""

(The XML-RPC Home page and the XML-RPC HOW-TO both provide further detail on the XML-RPC specification.)

A simple XML-RPC service

This simple service test.battingOrder accepts a positive integer < 51 as the parameter posn and returns a string containing the name of the US state occupying that ranking in the order of ratifying the constitution / joining the union.

 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
# -*- coding: iso-8859-1 -*-
import xmlrpclib
import pylons
from pylons import request
from pylons.controllers import XMLRPCController
from myapp.lib.base import *

states = [docmeta:'Delaware', 'Pennsylvania', 'New Jersey', 'Georgia', 'Connecticut', 
          'Massachusetts', 'Maryland', 'South Carolina', 'New Hampshire', 
          'Virginia', 'New York', 'North Carolina', 'Rhode Island', 'Vermont', 
          'Kentucky', 'Tennessee', 'Ohio', 'Louisiana', 'Indiana', 'Mississippi', 
          'Illinois', 'Alabama', 'Maine', 'Missouri', 'Arkansas', 'Michigan', 
          'Florida', 'Texas', 'Iowa', 'Wisconsin', 'California', 'Minnesota', 
          'Oregon', 'Kansas', 'West Virginia', 'Nevada', 'Nebraska', 'Colorado', 
          'North Dakota', 'South Dakota', 'Montana', 'Washington', 'Idaho', 
          'Wyoming', 'Utah', 'Oklahoma', 'New Mexico', 'Arizona', 'Alaska', 
          'Hawaii']

class RpctestController(XMLRPCController):

    def test_battingOrder(self, posn):
        """This docstring becomes the content of the
        returned value for system.methodHelp called with
        the parameter "test.battingOrder"). The method
        signature will be appended below ...
        """
        # XML-RPC checks agreement for arity and parameter datatype, so 
        # by the time we get called, we know we have an int.
        if posn > 0 and posn < 51:
            return states[docmeta:posn-1]
        else:
            # Technically, the param value is correct: it is an int.
            # Raising an error is inappropriate, so instead we
            # return a facetious message as a string.
            return 'Out of cheese error.'
    test_battingOrder.signature = [ [docmeta:'string', 'int'] ]

Testing the service

For developers using OS X, there's a handy XML/RPC client that is an extremely useful diagnostic tool when developing XML-RPC (it's free ... but not entirely bug-free). Or, you can just use the Python interpreter:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
>>> from pprint import pprint
>>> import xmlrpclib
>>> srvr = xmlrpclib.Server("http://example.com/rpctest/")
>>> pprint(srvr.system.listMethods())
[docmeta:'system.listMethods',
'system.methodHelp',
'system.methodSignature',
'test.battingOrder']
>>> print srvr.system.methodHelp('test.battingOrder')
This docstring becomes the content of the
returned value for system.methodHelp called with
the parameter "test.battingOrder"). The method
signature will be appended below ...

Method signature: [docmeta:['string', 'int']]
>>> pprint(srvr.system.methodSignature('test.battingOrder'))
[docmeta:['string', 'int']]
>>> pprint(srvr.test.battingOrder(12))
'North Carolina'

To debug XML-RPC servers from Python, create the client object using the optional verbose=1 parameter. You can then use the client as normal and watch as the XML-RPC request and response is displayed in the console.

Wrap-up

That just about covers the basics of using the Pylons XMLRPCController class. You are now in a position to go on to implement and publish a range of specialist, sophisticated RPC service methods; we look forward to your write-up in TechCrunch.

A [docmeta:companion document] deals with the slightly more ambitious (but also more useful) task of setting up a MetaWeblog API for blog publishing. Or you may prefer to review how you can use Pylons to implement some of the other non-HTML Internet publishing technologies: [docmeta:RSS], [docmeta:Atom], [docmeta:XMPP] and [docmeta:WSDL].

Site running on a free Atlassian Confluence Open Source Project License granted to Pylons. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.3.3 Build:#645 Feb 13, 2007) - Bug/feature request - Contact Administrators
Top