Forum Discussion

L4L7_53191's avatar
L4L7_53191
Icon for Nimbostratus rankNimbostratus
Sep 21, 2009

New Python SOAP library - SUDS!

There's an excellent new SOAP library for Python, called Suds, that holds a whole bunch of promise: It's actively maintained; the author is extremely helpful, responsive, and motivated to make a killer library; it's very 'Pythonic' in the way it handles things; and it's a pure client implementation.

 

The drawback? It's about as strongly-typed as I've seen in a dynamically typed Python world! This means that you need to create type objects by hand, very much akin to the way Java makes you do it. For example, to pass an argument to, say, get_default_pool_name, you need to create a Common.StringSequence object then pass it in (see the sample code below for an example of this).

 

 

The point of all of this is that, as some recent threads have noted, we're moving pyControl over to this new library. ZSI had some limitations that simply proved too difficult to overcome: Faults weren't handled well, it generates a ton of unused code for no reason, and we're locked into Python 2.5, for starters. The new PyControl WILL NOT be backward compatible in any way, so please take particular note of this...if you try and simply move code over, it'll break.

 

 

As of now, a very rough-and-ready version of pyControl2 has been written but the typing is proving a bit challenging to handle in a truly generic an portable way that will work consistently across all of the iControl WSDLs. If anyone out there is interested in helping us look into ways to do this cleanly, please let us know! As of now, there's no ETA on a formal release for PC2, no documentation, etc...we're very early into the project with far too little time.

 

 

At any rate, here's a sample that will hopefully get some of you started playing around with SUDS. Hopefully it'll generate some interest with the f5/Python user community out there so we can get some extra eyes on PC2 and make it a killer package.

 

  
 !/bin/env python  
  Small example of how to use the Python suds library with iControl.  
  See comments for a description of each section.  
  **Note: this requires suds version 0.3.6  
  
 import sys  
 import logging  
 from urllib import pathname2url  
 from suds.client import Client  
  
 try:  
      from suds.xsd.doctor import Import, ImportDoctor  
 except:   
      print "Requires suds 0.3.6 or higher!"  
      sys.exit()  
  
  Setup a log to see details on what is going on.  
  
 logging.basicConfig(level=logging.INFO)  
 logging.getLogger('suds.client').setLevel(logging.DEBUG)  
  
  Create the URL. Note that you can point to the BigIP or the filesystem.  
  On windows, something like this works:  
  url = 'file:' + pathname2url('c:\\tmp') + '/LocalLB.VirtualServer.wsdl'  
  Here, I'm grabbing it from a lab box and snagging the LocalLB.VirtualServer  
  wsdl.  
  
 url = 'https://192.168.1.245/iControl/iControlPortal.cgi?WSDL=LocalLB.VirtualServer' 
   
  Fix the missing import on our WSDLS.  
 imp = Import('http://schemas.xmlsoap.org/soap/encoding/')  
 doctor = ImportDoctor(imp)  
  
  Create the 'client' object. Call against this object for your methods.  
 c = Client(url, doctor = doctor, username = 'admin', password = 'admin')  
  
  Suds sets up a file cache that stores some common content, like your wsdl  
  and any other basic GET style info. Uncomment to disable the cache.  
  
 c.set_options(cache=None)  
  
  Setup your endpoint, username, password, etc. against the object. Very  
  pythonic! Do this by setting options attributes.   
  
 c.options.username = 'admin'  
 c.options.password = 'admin'  
 c.options.location = 'https://192.168.1.245/iControl/iControlPortal.cgi'  
  
  set the separator so we can create types. Python doesn't like using dot  
  notations inside of the WSDLS, which are valid according to the spec. This accomodates dot  
  notation. Special thanks to Jeff Ortel for adding this feature.  
 c.factory.separator('_')  
  
  Call a basic method to get a list of pools on the box.  
 virtuals = c.service.get_list()  
  
  Print the returned list. Your list is contained in the 'item' attribute of  
  the returned object.  
  
 for x in virtuals.item:  
     print x  
  
  Now, we'll create a type and pass it in as a keyword argument to a call. It  
  gets way more complex than this but we'll start slow...this part is a little java like.  
  Suds is very explicit with its typing. Overall, this is a very good thing but it   
  makes for some challenges with more type-heavy calls (like Virtual Server  
  create, for example).  
  Create a type of 'StringSequence'. We'll set attributes here and pass this  
  object into the keyword arguments. To create types, use the 'factory' object.  
  
 vs_name_list = c.factory.create('Common.StringSequence')  
 vs_name_list.item = virtuals.item  
  
  Now let's call a method that allows us to pass in the type.  
 default_pools = c.service.get_default_pool_name(virtual_servers = vs_name_list)  
  
  Now we'll print them after we zip() them together.  
 combined = zip(virtuals.item, default_pools.item)  
  
 for x in combined:  
      print "%s => %s" % (x[0], x[1])  
 

 

If you are interested in actively helping with this library, please post back with your email address and I will contact you with a version. Note that this IS NOT intended for any sort of production use now, and absolutely will change in the coming months.

 

 

-Matt
  • Sorry about the terrible formatting of the code - I've tried two times to fix it but I am unable to, for some reason...

     

     

    Posted to code share here: http://devcentral.f5.com/wiki/default.aspx/iControl/SudsPythonExample.html

     

     

    -Matt