Code

Changes between Version 22 and Version 23 of XML-RPC


Ignore:
Timestamp:
06/29/07 06:52:47 (7 years ago)
Author:
Paul Bx <pb@…>
Comment:

reverted vandalism

Legend:

Unmodified
Added
Removed
Modified
  • XML-RPC

    v22 v23  
    1 cinderella%252Bglass%252Bslipper%252Bshoes%252B%252B%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fcinderella%25252Dglass%25252Dslipper%25252Dshoes.html%252B%25255Dcinderella%252Bglass%252Bslipper%252Bshoes%25255B%25252FURL%25255D%252B%252B%252B%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fcinderella%25252Dglass%25252Dslipper%25252Dshoes.html%252B%25253Ecinderella%252Bglass%252Bslipper%252Bshoes%25253C%25252Fa%25253E%252B%252B%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fcinderella%25252Dglass%25252Dslipper%25252Dshoes.html%252Bcinderella%252Bglass%252Bslipper%252Bshoes%252B%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fcinderella%25252Dglass%25252Dslipper.html%252B%25253Ecinderella%252Bglass%252Bslipper%25253C%25252Fa%25253E%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fcinderellas%25252Dglass%25252Dslipper.html%252B%25253Ecinderellas%252Bglass%252Bslipper%25253C%25252Fa%25253E%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fkorean%25252Ddrama%25252Dglass%25252Dslipper.html%252B%25255Dkorean%252Bdrama%252Bglass%252Bslipper%25255B%25252FURL%25255D%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fshattering%25252Dthe%25252Dglass%25252Dslipper.html%252B%25253Eshattering%252Bthe%252Bglass%252Bslipper%25253C%25252Fa%25253E%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Findex.html%252B%25255Dglass%252Bslipper%25255B%25252FURL%25255D%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fcinderella%25252Dglass%25252Dslipper.html%252B%25255Dcinderella%252Bglass%252Bslipper%25255B%25252FURL%25255D%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fcinderella%25252Dand%25252Dthe%25252Dlittle%25252Dglass%25252Dslipper.html%252B%25253Ecinderella%252Band%252Bthe%252Blittle%252Bglass%252Bslipper%25253C%25252Fa%25253E%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fcinderellas%25252Dglass%25252Dslipper.html%252B%25255Dcinderellas%252Bglass%252Bslipper%25255B%25252FURL%25255D%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fcinderella%25252Dglass%25252Dslipper%25252Dwedding%25252Dfavor.html%252B%25253Ecinderella%252Bglass%252Bslipper%252Bwedding%252Bfavor%25253C%25252Fa%25253E%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fglass%25252Dslipper%25252Dwedding%25252Dshoes.html%252B%25253Eglass%252Bslipper%252Bwedding%252Bshoes%25253C%25252Fa%25253E%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fkorean%25252Ddrama%25252Dglass%25252Dslipper.html%252B%25253Ekorean%252Bdrama%252Bglass%252Bslipper%25253C%25252Fa%25253E%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fcinderella%25252Dglass%25252Dslipper%25252Dshoes.html%252B%25255Dcinderella%252Bglass%252Bslipper%252Bshoes%25255B%25252FURL%25255D%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fcinderella%25252Dand%25252Dthe%25252Dlittle%25252Dglass%25252Dslipper.html%252B%25255Dcinderella%252Band%252Bthe%252Blittle%252Bglass%252Bslipper%25255B%25252FURL%25255D%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fcinderella%25252Dglass%25252Dslipper%25252Dshoes.html%252B%25253Ecinderella%252Bglass%252Bslipper%252Bshoes%25253C%25252Fa%25253E%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fglass%25252Dslipper%25252Dboston.html%252B%25255Dglass%252Bslipper%252Bboston%25255B%25252FURL%25255D%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fshattering%25252Dthe%25252Dglass%25252Dslipper.html%252B%25255Dshattering%252Bthe%252Bglass%252Bslipper%25255B%25252FURL%25255D%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Findex.html%252B%25253Eglass%252Bslipper%25253C%25252Fa%25253E%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fglass%25252Dslipper%25252Dwedding%25252Dshoes.html%252B%25255Dglass%252Bslipper%252Bwedding%252Bshoes%25255B%25252FURL%25255D%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fglass%25252Dslipper%25252Dboston.html%252B%25253Eglass%252Bslipper%252Bboston%25253C%25252Fa%25253E%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Fglass%25252Dslipper%25252Fcinderella%25252Dglass%25252Dslipper%25252Dwedding%25252Dfavor.html%252B%25255Dcinderella%252Bglass%252Bslipper%252Bwedding%252Bfavor%25255B%25252FURL%25255D%25250D%25250Aa 
     1= XML-RPC = 
     2 
     3NOTE: All credit for this code goes to Crast in irc.freenode.net:#django... 
     4 
     5This uses SimpleXMLRPCDispatcher which is part of the standard Python lib in 2.4 (And possibly earlier versions). 
     6 
     7 
     8In discussing ways of handling XML-RPC for Django, I realised I really needed a way to do it without patching Django's code.  Crast in #django came up with a great solution, which I have modified and tweaked a bit. 
     9 
     10I've included it here.  Feel free to fiddle with it and make it your own ... All this code is '''post-mr''' 
     11 
     12Any crappy & garbage code is completely mine; I'm still learning Python so bear with me.  The hacks I added for self-documentation output are just that; any improvements to them would probably be a good thing. 
     13 
     14First, setup your urls.py to map an XML-RPC service: 
     15 
     16 
     17{{{ 
     18#!python 
     19urlpatterns = patterns('', 
     20    # XML-RPC 
     21     (r'^xml_rpc_srv/', 'yourproject.yourapp.xmlrpc.rpc_handler'), 
     22) 
     23}}} 
     24 
     25 
     26Then, in the appropriate place, create a file called xmlrpc.py 
     27 
     28 
     29{{{ 
     30#!python 
     31# Patchless XMLRPC Service for Django 
     32# Kind of hacky, and stolen from Crast on irc.freenode.net:#django 
     33# Self documents as well, so if you call it from outside of an XML-RPC Client 
     34# it tells you about itself and its methods 
     35# 
     36# Brendan W. McAdams <brendan.mcadams@thewintergrp.com> 
     37 
     38# SimpleXMLRPCDispatcher lets us register xml-rpc calls w/o 
     39# running a full XMLRPC Server.  It's up to us to dispatch data 
     40 
     41from SimpleXMLRPCServer import SimpleXMLRPCDispatcher 
     42from django.http import HttpResponse 
     43 
     44# Create a Dispatcher; this handles the calls and translates info to function maps 
     45#dispatcher = SimpleXMLRPCDispatcher() # Python 2.4 
     46dispatcher = SimpleXMLRPCDispatcher(allow_none=False, encoding=None) # Python 2.5 
     47 
     48  
     49 
     50def rpc_handler(request): 
     51        """ 
     52        the actual handler: 
     53        if you setup your urls.py properly, all calls to the xml-rpc service 
     54        should be routed through here. 
     55        If post data is defined, it assumes it's XML-RPC and tries to process as such 
     56        Empty post assumes you're viewing from a browser and tells you about the service. 
     57        """ 
     58 
     59        response = HttpResponse() 
     60        if len(request.POST): 
     61                response.write(dispatcher._marshaled_dispatch(request.raw_post_data)) 
     62        else: 
     63                response.write("<b>This is an XML-RPC Service.</b><br>") 
     64                response.write("You need to invoke it using an XML-RPC Client!<br>") 
     65                response.write("The following methods are available:<ul>") 
     66                methods = dispatcher.system_listMethods() 
     67 
     68                for method in methods: 
     69                        # right now, my version of SimpleXMLRPCDispatcher always 
     70                        # returns "signatures not supported"... :( 
     71                        # but, in an ideal world it will tell users what args are expected 
     72                        sig = dispatcher.system_methodSignature(method) 
     73 
     74                        # this just reads your docblock, so fill it in! 
     75                        help =  dispatcher.system_methodHelp(method) 
     76 
     77                        response.write("<li><b>%s</b>: [%s] %s" % (method, sig, help)) 
     78 
     79                response.write("</ul>") 
     80                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>') 
     81 
     82        response['Content-length'] = str(len(response.content)) 
     83        return response 
     84 
     85def multiply(a, b): 
     86        """ 
     87        Multiplication is fun! 
     88        Takes two arguments, which are multiplied together. 
     89        Returns the result of the multiplication! 
     90        """ 
     91        return a*b 
     92 
     93# you have to manually register all functions that are xml-rpc-able with the dispatcher 
     94# the dispatcher then maps the args down. 
     95# The first argument is the actual method, the second is what to call it from the XML-RPC side... 
     96dispatcher.register_function(multiply, 'multiply') 
     97}}} 
     98 
     99That's it! 
     100 
     101You can pretty much write a standard python function in there, just be sure to register it with the dispatcher when you're done.   
     102 
     103Here's a quick and dirty client example for testing: 
     104 
     105{{{ 
     106#!python 
     107import sys 
     108import xmlrpclib 
     109rpc_srv = xmlrpclib.ServerProxy("http://localhost:8000/xml_rpc_srv/") 
     110result = rpc_srv.multiply( int(sys.argv[1]), int(sys.argv[2])) 
     111print "%d * %d = %d" % (sys.argv[1], sys.argv[2], result) 
     112}}} 
     113 
     114Based 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). 
     115 
     116Have fun! 
     117 
     118- [mailto:brendan.mcadams@NOSPAM.thewintergrp.com  Brendan W. McAdams <brendan.mcadams@NOSPAM.thewintergrp.com>] 
     119 
     120---- 
     121 
     122I wrote up [http://www.personal-api.com/train/2007/feb/01/pingbacks-xml-rpc-and-django/ a modified version of the XML-RPC view] that uses a template for documentation. -- [mailto:hackerblinks+django@gmail.com Adam Blinkinsop <hackerblinks+django@gmail.com>] 
     123 
     124---- 
     125 
     126I've taken the basics of the SimpleXMLRPCDispatcher above and have turned it into a distributable Django app, [http://code.google.com/p/django-xmlrpc django_xmlrpc]. -- [mailto:graham.binns+django-xmlrpc@gmail.com Graham Binns]