Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Introspecting a WSDL with Python Zeep

Tags:

I am attempting to use Zeep to describe the operations and types in a given WSDL, so that a program knows the operation names, their parameter names, the parameter types, and parameter attributes.

This info will be used to dynamically generate a UI for a given WSDL.

What I have got so far is just the string representations of the operations and types. Using code similar to what is found in this answer.

Here's an example:

from zeep import Client import operator  wsdl = 'http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl' client = Client(wsdl)  # get each operation signature for service in client.wsdl.services.values():     print("service:", service.name)     for port in service.ports.values():         operations = sorted(             port.binding._operations.values(),             key=operator.attrgetter('name'))          for operation in operations:             print("method :", operation.name)             print("  input :", operation.input.signature())             print()     print()  # get a specific type signature by name complextype = client.get_type('ns0:CartGetRequest') print(complextype.name) print(complextype.signature()) 

This gives an output like the following (shortened for brevity)

[...]  method : CartCreate   input : MarketplaceDomain: xsd:string, AWSAccessKeyId: xsd:string, AssociateTag: xsd:string, Validate: xsd:string, XMLEscaping: xsd:string, Shared: ns0:CartCreateRequest, Request: ns0:CartCreateRequest[]  method : CartGet   input : MarketplaceDomain: xsd:string, AWSAccessKeyId: xsd:string, AssociateTag: xsd:string, Validate: xsd:string, XMLEscaping: xsd:string, Shared: ns0:CartGetRequest, Request: ns0:CartGetRequest[]  [...]   CartGetRequest {http://webservices.amazon.com/AWSECommerceService/2011-08-01}CartGetRequest(CartId: xsd:string, HMAC: xsd:string, MergeCart: xsd:string, ResponseGroup: xsd:string[]) 

The string representations returned by .signature() have the names and types, but I don't know how to parse them out individually. I have tried looping over each objects attrs with dir() as well, and they don't contain this info. It seems to be nested much deeper.

I could parse the string representations themselves, but then I am also missing whether or not the parameter is optional (more specifically, if it has the attribute minOccurs=0

It seems like SOAPpy actually has this functionality, but isn't maintained anymore.

So is there a way to introspect a WSDL with zeep that provides granular information about each operation, it's parameter names, types, and attributes similar to the SOAPpy implementation? Or should I parse the signature, or alternatively, parse the WSDL with a regular XML parser.

like image 541
jesse_galley Avatar asked Apr 29 '18 17:04

jesse_galley


1 Answers

Based on the answer from jordanm, I used the following to get all of the data I needed on the available methods

from zeep import Client from pprint import pprint  wsdl = 'http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl' client = Client(wsdl)   def parseElements(elements):     all_elements = {}     for name, element in elements:         all_elements[name] = {}         all_elements[name]['optional'] = element.is_optional         if hasattr(element.type, 'elements'):             all_elements[name]['type'] = parseElements(                 element.type.elements)         else:             all_elements[name]['type'] = str(element.type)      return all_elements   interface = {} for service in client.wsdl.services.values():     interface[service.name] = {}     for port in service.ports.values():         interface[service.name][port.name] = {}         operations = {}         for operation in port.binding._operations.values():             operations[operation.name] = {}             operations[operation.name]['input'] = {}             elements = operation.input.body.type.elements             operations[operation.name]['input'] = parseElements(elements)         interface[service.name][port.name]['operations'] = operations   pprint(interface) 
like image 54
jesse_galley Avatar answered Sep 18 '22 22:09

jesse_galley