Forum Discussion
L4L7_53191
Nimbostratus
Sep 21, 2009New 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
- L4L7_53191
Nimbostratus
Sorry about the terrible formatting of the code - I've tried two times to fix it but I am unable to, for some reason...
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects