Wrong (?) datatype generated with soaplib

621 views Asked by At

I'm having a problem with soaplib. I've the following function provided by a web service :

@soap(Integer, Integer, _returns=Integer)
def test(self, n1, n2):
    return n1 + n2

The corresponding declaration for the datatypes in the generated WSDL file is

<xs:complexType name="test">
  <xs:sequence>
    <xs:element name="n1" type="xs:integer" minOccurs="0" nillable="true"/>
    <xs:element name="n2" type="xs:integer" minOccurs="0" nillable="true"/>   
  </xs:sequence> 
</xs:complexType> 
<xs:complexType> name="testResponse">   
  <xs:sequence>
    <xs:element name="testResult" type="xs:integer" minOccurs="0" nillable="true"/>     
  </xs:sequence> 
</xs:complexType>

When I use some IDE (Visual Studio, PowerBuilder) to generate code from that WSDL file, whatever the IDE, it generates two classes for test and for testResponse, whose attributes are Strings.

Does anyone know if I can tweak my Python declaration so that I avoid complexType and obtain real Integer datatype on my client side?

3

There are 3 answers

0
FlipMcF On BEST ANSWER

Fought with the same thing, but couldn't move away from soaplib.

So, I monkeypatch it this way:

from soaplib.serializers.primitive import Integer

class BetterInteger(Integer):
   __type_name__ = "int"

Integer = BetterInteger

And then move on with life.

However, the XSD spec defines both 'integer': "Represents a signed integer. Values may begin with an optional "+" or "-" sign. Derived from the decimal datatype." and 'int' "Represents a 32-bit signed integer in the range [-2,147,483,648, 2,147,483,647]. Derived from the long datatype."

So, the better solution is:

from soaplib.serializers.primitive import Integer

class Int32(Integer):
   __type_name__ = "int"

And use your new 'Int32' class to type your input parameters.

[soaplib 1.0.0]

0
Nilesh On

I checked your code but i get same output. I am using suds to parse the values.

In [3]: from suds import client

In [4]: cl = client.Client('http://localhost:8080/?wsdl')

In [5]: cl.service.test(10,2)
Out[5]: 12

But when i check the type of that value.

In [6]: type(cl.service.test(10,2))
Out[6]: <class 'suds.sax.text.Text'>

So SOAPLIB will be return string but from type of that data you can convert it.

I check the response by writing this

@soap(_returns=Integer)
    def test(self):
        return 12

So i get in SOA Client Plugin of Firefox response as

<?xml version='1.0' encoding='utf-8'?>
<senv:Envelope 
      xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing" 
      xmlns:plink="http://schemas.xmlsoap.org/ws/2003/05/partner-link/" 
      xmlns:xop="http://www.w3.org/2004/08/xop/include"                
      xmlns:senc="http://schemas.xmlsoap.org/soap/encoding/" 
      xmlns:s12env="http://www.w3.org/2003/05/soap-envelope/"  
      xmlns:s12enc="http://www.w3.org/2003/05/soap-encoding/"  
      xmlns:xs="http://www.w3.org/2001/XMLSchema"    
      xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
      xmlns:senv="http://schemas.xmlsoap.org/soap/envelope/"  
      xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> 

      <senv:Body>
           <tns:testResponse>
               <tns:testResult>
                   12
               </tns:testResult>
           </tns:testResponse>
     </senv:Body>
</senv:Envelope>

From XML you cant get raw integer data.

0
Sun Wukong On

OK, not all datatypes of XSD are defined in soaplib. Integer is defined in soaplib and is seen in the WSDL file as an integer, which the .NET framework (used by PowerBuilder) failed to understand. Int is OK for .NET/PowerBuilder but soaplib isn't defined in soaplib.

Thus, I moved from soaplib to rpclib. Those libs are very close (one is a fork of the other).