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