Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SUDS - programmatic access to methods and types

Tags:

I'm investigating SUDS as a SOAP client for python. I want to inspect the methods available from a specified service, and the types required by a specified method.

The aim is to generate a user interface, allowing users to select a method, then fill in values in a dynamically generated form.

I can get some information on a particular method, but am unsure how to parse it:

client = Client(url) method = client.sd.service.methods['MyMethod'] 

I am unable to programmaticaly figure out what object type I need to create to be able to call the service

obj = client.factory.create('?')  res = client.service.MyMethod(obj, soapheaders=authen) 

Does anyone have some sample code?

like image 718
GHZ Avatar asked Oct 28 '08 00:10

GHZ


People also ask

What is suds object?

Suds is a lightweight library that uses SOAP based clients for python. SOAP is an RPC (Remote Procedure Call) that uses object-oriented protocol. Suds is actually lightweight SOAP python client that provides a service proxy for web services.

What is suds in Python?

Install Suds Suds is a SOAP module for Python, which allows Python to consume wsdl files. Setuptools that you installed in the previous step includes an Easy Install program that you can use to install the correct version of suds. Download the suds egg from https://pypi.python.org/pypi/suds.

What is suds package?

GitHub - suds-community/suds: Suds is a lightweight SOAP python client for consuming Web Services. A community fork of the jurko fork.


2 Answers

Okay, so SUDS does quite a bit of magic.

A suds.client.Client, is built from a WSDL file:

client = suds.client.Client("http://mssoapinterop.org/asmx/simple.asmx?WSDL") 

It downloads the WSDL and creates a definition in client.wsdl. When you call a method using SUDS via client.service.<method> it's actually doing a whole lot of recursive resolve magic behind the scenes against that interpreted WSDL. To discover the parameters and types for methods you'll need to introspect this object.

For example:

for method in client.wsdl.services[0].ports[0].methods.values():     print '%s(%s)' % (method.name, ', '.join('%s: %s' % (part.type, part.name) for part in method.soap.input.body.parts)) 

This should print something like:

echoInteger((u'int', http://www.w3.org/2001/XMLSchema): inputInteger) echoFloatArray((u'ArrayOfFloat', http://soapinterop.org/): inputFloatArray) echoVoid() echoDecimal((u'decimal', http://www.w3.org/2001/XMLSchema): inputDecimal) echoStructArray((u'ArrayOfSOAPStruct', http://soapinterop.org/xsd): inputStructArray) echoIntegerArray((u'ArrayOfInt', http://soapinterop.org/): inputIntegerArray) echoBase64((u'base64Binary', http://www.w3.org/2001/XMLSchema): inputBase64) echoHexBinary((u'hexBinary', http://www.w3.org/2001/XMLSchema): inputHexBinary) echoBoolean((u'boolean', http://www.w3.org/2001/XMLSchema): inputBoolean) echoStringArray((u'ArrayOfString', http://soapinterop.org/): inputStringArray) echoStruct((u'SOAPStruct', http://soapinterop.org/xsd): inputStruct) echoDate((u'dateTime', http://www.w3.org/2001/XMLSchema): inputDate) echoFloat((u'float', http://www.w3.org/2001/XMLSchema): inputFloat) echoString((u'string', http://www.w3.org/2001/XMLSchema): inputString) 

So the first element of the part's type tuple is probably what you're after:

>>> client.factory.create(u'ArrayOfInt') (ArrayOfInt){    _arrayType = ""    _offset = ""    _id = ""    _href = ""    _arrayType = ""  } 

Update:

For the Weather service it appears that the "parameters" are a part with an element not a type:

>>> client = suds.client.Client('http://www.webservicex.net/WeatherForecast.asmx?WSDL') >>> client.wsdl.services[0].ports[0].methods.values()[0].soap.input.body.parts[0].element (u'GetWeatherByZipCode', http://www.webservicex.net) >>> client.factory.create(u'GetWeatherByZipCode') (GetWeatherByZipCode){    ZipCode = None  } 

But this is magic'd into the parameters of the method call (a la client.service.GetWeatherByZipCode("12345"). IIRC this is SOAP RPC binding style? I think there's enough information here to get you started. Hint: the Python command line interface is your friend!

like image 168
sj26 Avatar answered Oct 04 '22 23:10

sj26


According to suds documentation, you can inspect service object with __str()__. So the following gets a list of methods and complex types:

from suds.client import Client;  url = 'http://www.webservicex.net/WeatherForecast.asmx?WSDL' client = Client(url)  temp = str(client); 

The code above produces following result (contents of temp):

Suds ( https://fedorahosted.org/suds/ )  version: 0.3.4 (beta)  build: R418-20081208  Service ( WeatherForecast ) tns="http://www.webservicex.net"    Prefixes (1)       ns0 = "http://www.webservicex.net"    Ports (2):       (WeatherForecastSoap)          Methods (2):             GetWeatherByPlaceName(xs:string PlaceName, )             GetWeatherByZipCode(xs:string ZipCode, )          Types (3):             ArrayOfWeatherData             WeatherData             WeatherForecasts       (WeatherForecastSoap12)          Methods (2):             GetWeatherByPlaceName(xs:string PlaceName, )             GetWeatherByZipCode(xs:string ZipCode, )          Types (3):             ArrayOfWeatherData             WeatherData             WeatherForecasts 

This would be much easier to parse. Also every method is listed with their parameters along with their types. You could, probably, even use just regular expression to extract information you need.

like image 36
artdanil Avatar answered Oct 05 '22 01:10

artdanil