Reputation: 180
using zeep 3.4.0
wsdl is looking for the following information in header
<soapenv:Header>\n
<vv:sessionHeader soapenv:mustUnderstand=\"1\">\n
<vv:sessionToken>\n
<vv:Token1 xmlns:vv=\"http://www.z.com/zTypes.xsd\">{{Token1Token}}
</vv:Token1>\n
<vv:Token2 xmlns:vv=\"http://www.z.com/zTypes.xsd\">{{Token2Token}}
</vv:Token2>\n
</vv:sessionToken>\n
</vv:sessionHeader>\n
I am passing parameters to _soapheaders as follows
headerQ = xsd.Element('Header',xsd.ComplexType ([
xsd.Element('sessionHeader',xsd.ComplexType ([
xsd.Element('sessionToken', xsd.ComplexType ([
xsd.Element('Token1',xsd.String()),
xsd.Element('Token2',xsd.String())
]))
]))
]))
header_value1 = headerQ({'Token1':Token1T, 'Token2':Token2T} )
client.set_default_soapheaders(header_value1)
header_value1 looks like this
{
'sessionHeader': {
'Token1': 'abcdef=',
'Token2': 'ghijkl='
}
}
I get the following error:
line 365, in _serialize_header
raise ValueError("Invalid value given to _soapheaders")
_serialize_header expects header_value1 to be either a list or a dictionary
isinstance(header_value1,dict) returns False
Questions:
Upvotes: 1
Views: 600
Reputation: 36
Debugging things with Zeep is always a bit of a challenge, but here's a working implementation:
In order to correctly render two elements (Token1 and Token2) you need a xsd:Sequence element:
headerQ = xsd.Element('Header', xsd.ComplexType([
xsd.Element('{http://www.z.com/zTypes.xsd}sessionHeader', xsd.ComplexType([
xsd.Element('{http://www.z.com/zTypes.xsd}sessionToken', xsd.ComplexType(
xsd.Sequence([
xsd.Element('{http://www.z.com/zTypes.xsd}Token1', xsd.String()),
xsd.Element('{http://www.z.com/zTypes.xsd', xsd.String())
])))
], attributes=[xsd.Attribute('mustUnderstand', xsd.Boolean())
]))
]))
Providing the QNames instead of raw element names will take care of the namespaces and finally you set the attributes on the sessionToken type definition. If your soap server refuses to accept "true" then you can use an xsd:Integer type, or you can rewrite "true" to "1" using an egress plugin as shown here
Setting the header value works as you tried, although you need to wrap into a list:
header_value1 = headerQ(
{'mustUnderstand': True,
'sessionToken': {'Token1': 'Token1T',
'Token2': 'Token2T'}
}
)
client.set_default_soapheaders([header_value1])
This gives the header section:
<Header>
<ns0:sessionHeader xmlns:ns0="http://www.z.com/zTypes.xsd" mustUnderstand="true">
<ns0:sessionToken>
<ns0:Token1>Token1T</ns0:Token1>
<ns0:Token2>Token2T</ns0:Token2>
</ns0:sessionToken>
</ns0:sessionHeader>
</Header>
Upvotes: 2
Reputation: 180
rather than using the built in method, I got it working with
header_value1 = {'sessionHeader': {'sessionToken': { \
'primary': token1, secondary': token2}}}
Upvotes: 0