Changes between Version 26 and Version 27 of XML-RPC


Ignore:
Timestamp:
Jul 13, 2007, 1:46:53 AM (17 years ago)
Author:
Simon G. <dev@…>
Comment:

spam revert

Legend:

Unmodified
Added
Removed
Modified
  • XML-RPC

    v26 v27  
    1 rubber%252Brain%252Bboot%252B%252B%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Frubber%25252Drain%25252Dboot.html%252B%25255Drubber%252Brain%252Bboot%25255B%25252FURL%25255D%252B%252B%252B%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Frubber%25252Drain%25252Dboot.html%252B%25253Erubber%252Brain%252Bboot%25253C%25252Fa%25253E%252B%252B%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Frubber%25252Drain%25252Dboot.html%252Brubber%252Brain%252Bboot%252B%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fwomens%25252Drain%25252Dboot.html%252B%25253Ewomens%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fkid%25252Drain%25252Dboot.html%252B%25253Ekid%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fwoman%25252Drain%25252Dboot.html%252B%25253Ewoman%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fkid%25252Drain%25252Dboot.html%252B%25255Dkid%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fchild%25252Drain%25252Dboot.html%252B%25253Echild%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Findex.html%252B%25255Drain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Frubber%25252Drain%25252Dboot.html%252B%25255Drubber%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fchild%25252Drain%25252Dboot.html%252B%25255Dchild%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fgucci%25252Drain%25252Dboot.html%252B%25253Egucci%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Findex.html%252B%25253Erain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fwomens%25252Drubber%25252Drain%25252Dboot.html%252B%25255Dwomens%252Brubber%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fwomens%25252Drain%25252Dboot.html%252B%25255Dwomens%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fburberry%25252Drain%25252Dboot.html%252B%25255Dburberry%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Frubber%25252Drain%25252Dboot.html%252B%25253Erubber%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fcoach%25252Drain%25252Dboot.html%252B%25253Ecoach%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fcoach%25252Drain%25252Dboot.html%252B%25255Dcoach%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fwoman%25252Drain%25252Dboot.html%252B%25255Dwoman%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fgucci%25252Drain%25252Dboot.html%252B%25255Dgucci%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fburberry%25252Drain%25252Dboot.html%252B%25253Eburberry%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fwomens%25252Drubber%25252Drain%25252Dboot.html%252B%25253Ewomens%252Brubber%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A3
     1rubber%252Brain%252Bboot%252B%252B%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Frubber%25252Drain%25252Dboot.html%252B%25255Drubber%252Brain%252Bboot%25255B%25252FURL%25255D%252B%252B%252B%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Frubber%25252Drain%25252Dboot.html%252B%25253Erubber%252Brain%252Bboot%25253C%25252Fa%25253E%252B%252B%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Frubber%25252Drain%25252Dboot.html%252Brubber%252Brain%252Bboot%252B%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fwomens%25252Drain%25252Dboot.html%252B%25253Ewomens%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fkid%25252Drain%25252Dboot.html%252B%25253Ekid%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fwoman%25252Drain%25252Dboot.html%252B%25253Ewoman%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fkid%25252Drain%25252Dboot.html%252B%25255Dkid%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fchild%25252Drain%25252Dboot.html%252B%25253Echild%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Findex.html%252B%25255Drain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Frubber%25252Drain%25252Dboot.html%252B%25255Drubber%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fchild%25252Drain%25252Dboot.html%252B%25255Dchild%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fgucci%25252Drain%25252Dboot.html%252B%25253Egucci%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Findex.html%252B%25253Erain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fwomens%25252Drubber%25252Drain%25252Dboot.html%252B%25255Dwomens%252Brubber%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fwomens%25252Drain%25252Dboot.html%252B%25255Dwomens%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fburberry%25252Drain%25252Dboot.html%252B%25255Dburberry%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Frubber%25252Drain%25252Dboot.html%252B%25253Erubber%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fcoach%25252Drain%25252Dboot.html%252B%25253Ecoach%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fcoach%25252Drain%25252Dboot.html%252B%25255Dcoach%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fwoman%25252Drain%25252Dboot.html%252B%25255Dwoman%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25255BURL%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fgucci%25252Drain%25252Dboot.html%252B%25255Dgucci%252Brain%252Bboot%25255B%25252FURL%25255D%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fburberry%25252Drain%25252Dboot.html%252B%25253Eburberry%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A%25253Ca%252Bhref%25253D%252Bhttp%25253A%25252F%25252Fgeocities.com%25252Fshoeshere%25252Frain%25252Dboots%25252Fwomens%25252Drubber%25252Drain%25252Dboot.html%252B%25253Ewomens%252Brubber%252Brain%252Bboot%25253C%25252Fa%25253E%25250D%25250A3= 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]
Back to Top