Hi,

I've been hacking up a little package that uses Suds' WSDL parsing to generate Python code that describes the service and its complex types using zope.interface semantics. This helps us in creating mocks for our remote SOAP service.

The code generator is here: http://bitbucket.org/optilude/wsdl2interface/src/tip/wsdl2interface.py ; if you want to test it, it's on PyPI: http://pypi.python.org/pypi/wsdl2interface

I'm getting quite confused by two things, though, probably because the internal Suds data structures are so comprehensive:

 - I'd like to output (as a comment) the return type for each method in the service interface. The 'print client' output doesn't have this. Any clues on where I should look?

 - In the WSDL file from our supplier, we seem to be getting one complex type for each service method. For example, we have 'addFavorite' as a complex type and 'addFavorite()' as a method. The method takes the same arguments as the complex type. In some other test services I used, that didn't happen. It may just be that I'm mis-understanding something about SOAP, but can you shed some light on why it's coming out like this, and whether I should be trying to filter out these types somehow?

Any hints?

Our WSDL file looks a bit like this (snipped and obfuscated slightly):

{{{
<definitions name='AcmeServiceBeanService' targetNamespace='http://ejb3.acme.boo.example.com/' xmlns='http://schemas.xmlsoap.org/wsdl/' xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:tns='http://ejb3.acme.boo.example.com/' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
 <types>
  <xs:schema targetNamespace='http://ejb3.acme.boo.example.com/' version='1.0' xmlns:tns='http://ejb3.acme.boo.example.com/' xmlns:xs='http://www.w3.org/2001/XMLSchema'>

   <xs:element name='addFavourite' type='tns:addFavourite'/>
   <xs:element name='addFavouriteResponse' type='tns:addFavouriteResponse'/>

   <xs:complexType name='addFavourite'>
    <xs:sequence>
     <xs:element minOccurs='0' name='tokenId' type='xs:string'/>
     <xs:element name='favoriteId' type='xs:short'/>
     <xs:element minOccurs='0' name='favoriteName' type='xs:string'/>
    </xs:sequence>
   </xs:complexType>

   <xs:complexType name='addFavouriteResponse'>
    <xs:sequence>
     <xs:element name='response' type='xs:int'/>
    </xs:sequence>
   </xs:complexType>

  </xs:schema>
 </types>

 <message name='AcmeServiceBean_addFavouriteResponse'>
  <part element='tns:addFavouriteResponse' name='addFavouriteResponse'></part>
 </message>

 <message name='AcmeServiceBean_addFavourite'>
  <part element='tns:addFavourite' name='addFavourite'></part>
 </message>

 <portType name='AcmeServiceBean'>
  <operation name='addFavourite' parameterOrder='addFavourite'>
   <input message='tns:AcmeServiceBean_addFavourite'></input>
   <output message='tns:AcmeServiceBean_addFavouriteResponse'></output>
  </operation>
 </portType>

 <binding name='AcmeServiceBeanBinding' type='tns:AcmeServiceBean'>
  <soap:binding style='document' transport='http://schemas.xmlsoap.org/soap/http'/>
  <operation name='addFavourite'>
   <soap:operation soapAction=''/>
   <input>
    <soap:body use='literal'/>
   </input>
   <output>
    <soap:body use='literal'/>
   </output>
  </operation>

 </binding>

 <service name='AcmeServiceBeanService'>
 
  <port binding='tns:AcmeServiceBeanBinding' name='AcmeServiceBeanPort'>
   <soap:address location='http://127.0.0.1:8080//AcmeService'/>
  </port>
 
 </service>
 
</definitions>
}}}

The Suds client looks like this:

{{{
Suds ( https://fedorahosted.org/suds/ )  version: 0.3.9 GA  build: R659-20100219

Service ( AcmeServiceBeanService ) tns="http://ejb3.acme.boo.example.com/"
   Prefixes (1)
      ns0 = "http://ejb3.acme.boo.example.com/"
   Ports (1):
      (AcmeServiceBeanPort)
         Methods (1):
            addFavourite(xs:string tokenId, xs:short favoriteId, xs:string favoriteName, )
         Types (2):
            addFavourite
            addFavouriteResponse
}}}

When I run the code generator, the output is:

{{{
from zope.interface import Interface, Attribute
from zope import schema

class IAddFavourite(Interface):
    """SOAP complex type ``{http://ejb3.acme.boo.example.com/}addFavourite``
    """

    tokenId = schema.TextLine(description=u"WSDL type: string")
    favoriteId = schema.Int(description=u"WSDL type: short")
    favoriteName = schema.TextLine(description=u"WSDL type: string")

class IAddFavouriteResponse(Interface):
    """SOAP complex type
    ``{http://ejb3.acme.boo.example.com/}addFavouriteResponse``
    """

    response = schema.Int(description=u"WSDL type: int")

WSDL_TYPES = {
    'addFavourite': IAddFavourite,
    'addFavouriteResponse': IAddFavouriteResponse
}


class IAcmeServiceBeanService(Interface):
    """SOAP service ``AcmeServiceBeanService`` with target namespace
    http://ejb3.acme.boo.example.com/.
    """

    def addFavourite(tokenId, favoriteId, favoriteName):
        """Parameters:
        
        ``tokenId`` -- string (optional)
        ``favoriteId`` -- short
        ``favoriteName`` -- string (optional)
        """

}}}

Thanks,
Martin