Zeep 复杂 Header

Zeep with Complex Header

使用 zeep 3.4.0

wsdl 正在 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

我正在将参数传递给 _soapheaders,如下所示

    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 看起来像这样

    {
        'sessionHeader': {
            'Token1': 'abcdef=',
            'Token2': 'ghijkl='
        }
    }

我收到以下错误:

    line 365, in _serialize_header
    raise ValueError("Invalid value given to _soapheaders")

_serialize_header 期望 header_value1 是列表或字典

isinstance(header_value1,dict) returns 假

问题:

我没有使用内置方法,而是使用

    header_value1 = {'sessionHeader': {'sessionToken': { \
    'primary': token1, secondary': token2}}}

使用 Zeep 进行调试总是有点挑战,但这是一个有效的实现:

为了正确呈现两个元素(Token1 和 Token2),您需要一个 xsd:Sequence 元素:

   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())
     ]))
   ]))

提供 QName 而不是原始元素名称将处理命名空间,最后您在 sessionToken 类型定义上设置属性。如果您的 soap 服务器拒绝接受“true”,那么您可以使用 xsd:Integer 类型,或者您可以使用出口插件将“true”重写为“1”,如 shown here

设置 header 值与您尝试的一样有效,尽管您需要包装到一个列表中:

header_value1 = headerQ(
  {'mustUnderstand': True,
   'sessionToken': {'Token1': 'Token1T',
                    'Token2': 'Token2T'}
  }
)
client.set_default_soapheaders([header_value1])

这给出了 header 部分:

<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>