Previous Page
Next Page

19.6. Distributed Computing

There are many standards for distributed computing, from simple Remote Procedure Call (RPC) ones to rich object-oriented ones such as CORBA. You can find many third-party Python modules that support these standards on the Internet.

The Python standard library supports both server and client use of a simple yet powerful standard known as XML-RPC. For in-depth coverage of XML-RPC, I recommend the book Programming Web Services with XML-RPC, by Simon St.Laurent and Joe Johnson (O'Reilly). XML-RPC uses HTTP or HTTPS as the underlying transport and encodes requests and replies in XML. For server-side support, see "The Message Classes of the rfc822 and mimetools Modules" on page 573. Client-side support is supplied by module xmlrpclib.

The xmlrcplib module supplies a class ServerProxy, which you instantiate to connect to an XML-RPC server. An instance s of ServerProxy is a proxy for the server it connects to: you call arbitrary methods on s, and s packages the method name and argument values as an XML-RPC request, sends the request to the XML-RPC server, receives the server's response, and unpacks the response as the method's result. The arguments to such method calls can be of any type supported by XML-RPC:


Boolean

The built-in bool constants TRue and False


Integers, floating-point numbers, strings, arrays

Passed and returned as Python int, float, Unicode, and list values


Structures

Passed and returned as Python dict values whose keys must be strings


Dates

Passed as instances of class xmlrpclib.DateTime; value is represented in seconds since the epoch, as in module time (see Chapter 12).


Binary data

Passed as instances of class xmlrpclib.Binary; value is an arbitrary byte string

Module xmlrpclib supplies several classes.

Binary

class Binary(x)

x is a Python string of arbitrary bytes. b wraps the bytes as an XML-RPC binary object.

DateTime

class DateTime(x)

x is the number of seconds since the epoch, as in module time, covered in "The time Module" on page 302.

ServerProxy

class ServerProxy(uri, transport=None, encoding='utf-8', verbose=False, allow_none=False)

The uri string is normally the server's URL and may be of the form 'protocol://user:pass@host/...' to include a username and password for basic authentication; protocol is http or https, and you normally do not pass optional argument transport, allowing the module to pick the right transport for the given protocol. You may optionally pass optional argument encoding as the name of the 8-bit encoding to use, verbose as TRue to get verbose debugging information during the following XML-RPC operations, and allow_none as true to add None to the set of data types supported (this requires a server that sports a popular but not universal extension to the basic XML-RPC protocol).

If the server at the given uri supports introspection, s supplies an attribute s.system that in turn supplies three methods:


s.system.listMethods( )

Returns a list of strings, one per each method supported by the server.


s.system.methodSignature( name)

Returns a list of strings, each a signature of method name on the server. A signature string is composed of type names separated by commas: first the type of the return value, then the type of each argument. When method name has no defined signature, s.server.methodSignature(name) returns some object that is not a list.


s.system.methodHelp( name)

Returns a string with help about method name. The string can be either plain text or HTML. When the method name has no defined help, s.server.methodHelp(name) returns an empty string ''.


The following example uses xmlrpclib to access O'Reilly's Meerkat open wire service (see http://www.oreillynet.com/meerkat/ for more information about Meerkat) and displays a few recent news items about Python:

import xmlrpclib

proxy = xmlrpclib.ServerProxy(
    'http://www.oreillynet.com/meerkat/xml-rpc/server.php')
results = proxy.meerkat.getItems({'search':'Python', 'num_items':7})

want_keys = 'title link description'.split( )
n = 0
for result in results:
    n = n + 1
    for key in want_keys:
        print '%d. %s: %s' % (n, key.title( ), result.get(key))
    print


Previous Page
Next Page