Making python xmlrpclib client log method calls

I’ve updated the steps described in this post, please see the revisited post.

I’m developing python scripting which uses XMLRPC. Every now and then I find myself in a situation where I wish I could just get the calls written to my terminal, in the order I called them in, including parameters – especially when I need support. This is what I came up with in my quest to find a decent way to make the XMLRPC API write each call before it’s actually invoked:

  1. import xmlrpclib
  2. import pprint
  3.  
  4. class MethodInvocationWriter:
  5.     def __init__(self, writer = pprint.pprint):
  6.         self._output_writer = writer
  7.  
  8.     def dumps(self, params, methodname, encoding='', 
  9.               allow_none = False):
  10.         self._output_writer("fire => %s%s" % (methodname, params))
  11.         return real_dumps(params, methodname, encoding = encoding, 
  12.                           allow_none = allow_none)
  13.  
  14. real_dumps = xmlrpclib.dumps
  15. xmlrpclib.dumps = MethodInvocationWriter().dumps 
  16.  
  17. if __name__ == '__main__':
  18.     client = xmlrpclib.ServerProxy(
  19.                "http://www.cookcomputing.com/xmlrpcsamples/RPC2.ashx"
  20.     )
  21.     print client.examples.getStateName(12)

When executed, it’ll return this:

  1. 'fire => examples.getStateName(12,)'
  2. Idaho

The xmlrpclib.dumps function is overriden with a custom method: XMLRPCLibOutputWriter.dumps. I don’t want to duplicate exiting code, so I keep a reference to the original dumps method: real_dumps. The ServerProxy will now call XMLRPCLibOutputWriter.dumps, which prints the name of the name of the method being called including parameters using the output_writer, and offloads the work to real_dumps at the end.

It would have been cleaner to override xmlrpclib.ServerProxy.__request, but access modifiers on __request prevented me from doing that.

Comments, questions or improvements? Let me know.

Leave a Reply

Your email address will not be published. Required fields are marked *