tags:

views:

249

answers:

1

How do I add complex types to a SOAP request?

I'm using WSDL2py generated requests, and trying to use the other TypeDefinitions that it made in the *_types.py file (like AccountInfo, for authentication, that goes into every request). Then passing it the wsdl2py generated server, and I'm getting this error:

>>> from AutomotiveDescriptionService6_client import *
>>> from AutomotiveDescriptionService6_types import *
>>> loc = AutomotiveDescriptionService6Locator()
>>> server = loc.getAutomotiveDescriptionService6Port()
>>> request = getDataVersions()
>>> auth = ns0.AccountInfo_Def()
>>> auth._accountName="**"
>>> auth._accountSecret="***"
>>> request._accountInfo = auth
>>> server.getDataVersions(request)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "AutomotiveDescriptionService6_client.py", line 38, in getDataVersions
    self.binding.Send(None, None, request, soapaction="", **kw)
  File "/usr/lib/pymodules/python2.6/ZSI/client.py", line 246, in Send
    sw.serialize(obj, tc)
  File "/usr/lib/pymodules/python2.6/ZSI/writer.py", line 117, in serialize
    elt = typecode.serialize(self.body, self, pyobj, **kw)
  File "/usr/lib/pymodules/python2.6/ZSI/TC.py", line 609, in serialize
    pyobj.typecode.serialize(elt, sw, pyobj, **kw)
  File "/usr/lib/pymodules/python2.6/ZSI/TCcompound.py", line 275, in serialize
    self.cb(elt, sw, pyobj, name=name, **kw)
  File "/usr/lib/pymodules/python2.6/ZSI/TCcompound.py", line 424, in cb
    what.serialize(elem, sw, v, **kw)
  File "/usr/lib/pymodules/python2.6/ZSI/TCcompound.py", line 275, in serialize
    self.cb(elt, sw, pyobj, name=name, **kw)
  File "/usr/lib/pymodules/python2.6/ZSI/TCcompound.py", line 437, in cb
    sw.Backtrace(elt))
ZSI.EvaluateException: Got None for nillable(False), minOccurs(1) element (urn:description6.kp.chrome.com,accountNumber), <ns1:accountInfo xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ZSI="http://www.zolera.com/schemas/ZSI/" xmlns:ns1="urn:description6.kp.chrome.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;&lt;/ns1:accountInfo&gt;
[Element trace: /SOAP-ENV:Body/ns1:DataVersionsRequest]

As you can see, it's easy to generate request objects, wsdl2py uses GED() to give us those, but it DOESN'T expose the classes that those requests need. For the life of me, I can't figure out how the hell to get that complex type properly into the request object, without getting that error. I've been trying to instantiate the definition in the **_types.py file, and I've been trying just plain dicts. NOTHING seems to work. Here's what the auto-generated definition looks like, any suggestions?

class ns0:
    targetNamespace = "urn:description6.kp.chrome.com"

    class AccountInfo_Def(ZSI.TCcompound.ComplexType, TypeDefinition):
        schema = "urn:description6.kp.chrome.com"
        type = (schema, "AccountInfo")
        def __init__(self, pname, ofwhat=(), attributes=None, extend=False, restrict=False, **kw):
            ns = ns0.AccountInfo_Def.schema
            TClist = [ZSI.TC.String(pname=(ns,"accountNumber"), aname="_accountNumber", minOccurs=1, maxOccurs=1, nillable=False, typed=False, encoded=kw.get("encoded")), ZSI.TC.String(pname=(ns,"accountSecret"), aname="_accountSecret", minOccurs=1, maxOccurs=1, nillable=False, typed=False, encoded=kw.get("encoded")), GTD("urn:description6.kp.chrome.com","Locale",lazy=False)(pname=(ns,"locale"), aname="_locale", minOccurs=1, maxOccurs=1, nillable=False, typed=False, encoded=kw.get("encoded"))]
            self.attribute_typecode_dict = attributes or {}
            if extend: TClist += ofwhat
            if restrict: TClist = ofwhat
            ZSI.TCcompound.ComplexType.__init__(self, None, TClist, pname=pname, inorder=0, **kw)
            class Holder:
                typecode = self
                def __init__(self):
                    # pyclass
                    self._accountNumber = None
                    self._accountSecret = None
                    return
            Holder.__name__ = "AccountInfo_Holder"
            self.pyclass = Holder
+1  A: 

So... found out that the problem is I needed to run wsdl2py with the --complextypes flag.This creates a whole slew of awesome methods inside of the reqeust object. methods like new_XXXXX where X is the name of the complex type that's required by that request.

hendrixski