Version 48 (modified by mandel, 5 years ago) (diff)

An error will happen in the mimetype is not set correctly when working with some js libs. I've changed the code to make sure that people get it right.

NOTE: All credit for this code goes to Crast in irc.freenode.net:#django...

# Patchless XMLRPC Service for Django
# Kind of hacky, and stolen from Crast on irc.freenode.net:#django
# Self documents as well, so if you call it from outside of an XML-RPC Client
# it tells you about itself and its methods
#
# Brendan W. McAdams <brendan.mcadams@thewintergrp.com>

# SimpleXMLRPCDispatcher lets us register xml-rpc calls w/o
# running a full XMLRPC Server.  It's up to us to dispatch data

from SimpleXMLRPCServer import SimpleXMLRPCDispatcher
from django.http import HttpResponse

# Create a Dispatcher; this handles the calls and translates info to function maps
#dispatcher = SimpleXMLRPCDispatcher() # Python 2.4
dispatcher = SimpleXMLRPCDispatcher(allow_none=False, encoding=None) # Python 2.5

 

def rpc_handler(request):
        """
        the actual handler:
        if you setup your urls.py properly, all calls to the xml-rpc service
        should be routed through here.
        If post data is defined, it assumes it's XML-RPC and tries to process as such
        Empty post assumes you're viewing from a browser and tells you about the service.
        """

        if len(request.POST):
                response = HttpResponse(mimetype="application/xml")
                response.write(dispatcher._marshaled_dispatch(request.raw_post_data))
        else:
                response = HttpResponse()
                response.write("<b>This is an XML-RPC Service.</b><br>")
                response.write("You need to invoke it using an XML-RPC Client!<br>")
                response.write("The following methods are available:<ul>")
                methods = dispatcher.system_listMethods()

                for method in methods:
                        # right now, my version of SimpleXMLRPCDispatcher always
                        # returns "signatures not supported"... :(
                        # but, in an ideal world it will tell users what args are expected
                        sig = dispatcher.system_methodSignature(method)

                        # this just reads your docblock, so fill it in!
                        help =  dispatcher.system_methodHelp(method)

                        response.write("<li><b>%s</b>: [%s] %s" % (method, sig, help))

                response.write("</ul>")
                response.write('<a href="http://www.djangoproject.com/"> <img src="http://media.djangoproject.com/img/badges/djangomade124x25_grey.gif" border="0" alt="Made with Django." title="Made with Django."></a>')

        response['Content-length'] = str(len(response.content))
        return response

def multiply(a, b):
        """
        Multiplication is fun!
        Takes two arguments, which are multiplied together.
        Returns the result of the multiplication!
        """
        return a*b

# you have to manually register all functions that are xml-rpc-able with the dispatcher
# the dispatcher then maps the args down.
# The first argument is the actual method, the second is what to call it from the XML-RPC side...
dispatcher.register_function(multiply, 'multiply')

That's it!

You can pretty much write a standard python function in there, just be sure to register it with the dispatcher when you're done.

Here's a quick and dirty client example for testing:

import sys
import xmlrpclib
rpc_srv = xmlrpclib.ServerProxy("http://localhost:8000/xml_rpc_srv/")
result = rpc_srv.multiply( int(sys.argv[1]), int(sys.argv[2]))
print "%d * %d = %d" % (sys.argv[1], sys.argv[2], result)

Based on experience, I do recommend that you use Dictionaries for your args rather than long args, but I think that's personal preference (It allows named arguments, eliminates 'out of order' argument issues and it makes the code more self-documenting).

Have fun!

  • Brendan W. McAdams

I wrote up a modified version of the XML-RPC view that uses a template for documentation. -- Adam Blinkinsop (Link is no longer valid. Author any chance for update it?)


I've taken the basics of the SimpleXMLRPCDispatcher above and have turned it into a distributable Django app, django_xmlrpc. -- Graham Binns


I've wrote pingback implementation on top of this XML-RPC dispatcher. --Alexander Solovyov


Testing your XML-RPC views using the Django test client

I wrote up a small how-to on how to test your XML-RPC views using the Django test client as an XML-RPC transport: http://www.technobabble.dk/2008/apr/02/xml-rpc-dispatching-through-django-test-client/

-- Christian Joergensen


Using the SimpleXMLRPCDispatcher above and integrating it with a JSONRPCDispatcher, I created a Django application that can handle both XMLRPC and JSONRPC requests. It uses a customizable Django template for self-documentation.

Back to Top