mvantellingen/python-zeep

passing a composite element to a service operation

giuliohome opened this issue · 1 comments

Given

client = Client('http://www.dneonline.com/calculator.asmx?WSDL')
AddType = client.get_element('ns0:Add')
sum = AddType(2,3)

sum is

{
    'intA': 2,
    'intB': 3
}

Now

client.service.Add(2,3)

and

client.service.Add(intA=2,intB=3)

both return 5

However, when trying to use the sum object directly, like this:

client.service.Add(sum)

it results in the error message: zeep.exceptions.ValidationError: Missing element intB (Add.intB)

To successfully use the sum object with client.service.Add, a workaround is required:

client.service.Add(**sum.__values__)

So, the issue is that the client.service.Add operation (and this is true for any wsdl soap operation of course) does not automatically recognize the sum object (its own input message) and requires the use of **sum.__values__ to extract and pass the values.

In this simple case, the issue is evident due to the presence of an exception. However, when a value is optional, it can become challenging to detect the problem.

I am going with the dictionary approach

However instead of creating an object from a type defined in the XSD you can also pass in a dictionary. Zeep will automatically convert this dict to the required object (and nested child objects) during the call.

This allows me to use the dictionary unpacking operator.

However, it's worth noting that the convention here in this Python client differs from what's typically done in JavaScript SOAP packages, where dictionaries are always passed as arguments directly to the SOAP operation functions without the need for unpacking, as shown, for example, here.