使用Zeep修改SOAP标头

时间:2019-04-19 10:34:53

标签: xml python-3.x soap wsdl zeep

我想使用Zeep(https://python-zeep.readthedocs.io/en/master/index.html)在python 3下建立一个Soap连接。但我不明白如何更改xml的标头和正文!

我想要拥有:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www...." xmlns:ns2="http://schemas....">
    <SOAP-ENV:Header>
        <ns2:UsernameToken>
            <Username>__USERNAME__</Username>
            <Password>__PASSWORD__</Password>
            <Reference>__REFERENCE__</Reference>
        </ns2:UsernameToken>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
        <ns1:requestAd/>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我已经完成:

import zeep

settings = zeep.Settings(strict=False, xml_huge_tree=True, extra_http_headers = {'http://www....','http://schemas...'})
wsdl = 'https://.......?wsdl'
client = zeep.Client(wsdl=wsdl,settings = settings)


header = zeep.xsd.Element(
        'UsernameToken', 
        zeep.xsd.ComplexType([ 
         zeep.xsd.Element('Username',zeep.xsd.String()), 
         zeep.xsd.Element('Password',zeep.xsd.String()), 
         zeep.xsd.Element('Reference',zeep.xsd.String()),
        ]) 
       )
header_value = header(UsernameToken={'Username':'__USERNAME__','Password':'__PASSWORD__','Reference':'__REFERENCE__'})

我的错误是: TypeError:ComplexType()获得了意外的关键字参数'UsernameToken'。签名:Username: xsd:string, Password: xsd:string, Reference: xsd:string

注意: 我尝试了文档中的所有解决方案,但没有任何效果(https://python-zeep.readthedocs.io/en/master/headers.html

2 个答案:

答案 0 :(得分:1)

当我在zeep中遇到同样的问题时,我使用了get_type()方法将数据嵌套在soap调用中。

"""index.py"""

import zeep

settings = zeep.Settings(strict=False,
                         xml_huge_tree=True,
                         extra_http_headers={'http://www....',
                                             'http://schemas...'})
wsdl = 'https://.......?wsdl'
client = zeep.Client(wsdl=wsdl, settings=settings)
usernameTokenRef = client.get_type('ns2:UsernameToken')
usernameTokenValues = usernameTokenRef(Username='__USERNAME__',
                                       Password='__PASSWORD__',
                                       Reference='__REFERENCE__')

# pass args for UsernameToken into header of soap call
# using _soapheaders arg when calling a service
response = client.service.SomeService(_soapheaders={'UsernameToken':
                                      usernameTokenValues})

答案 1 :(得分:0)

在这种情况下,错误消息非常有用,因为您不需要指定Header元素中只有一个子元素,Zeep会推断出它。

错误消息说,当尝试呈现复杂类型时,它期望“ Username”,“ Password”和“ Reference”,但是却获得了“ UsernameToken”。

如果您删除关键字参数“ UsernameToken”,您的代码将按编写的方式工作,这是一个有效的版本,请注意,您需要在列表中传递标头:

headerQ = Element('Header', ComplexType([
  Element('{http://test_ns.com}UsernameToken', ComplexType(
    Sequence([
      Element('Username', String()),
      Element('Password', String()),
      Element('Reference', String())
    ]))
  )
]))
header_value = headerQ({'Username': '__USERNAME__', 'Password': '__PASSWORD__', 
  'Reference': '__REFERENCE__'})
client.set_default_soapheaders([header_value])

这生成了以下肥皂头:

<soap-env:Header>
  <Header>
    <ns0:UsernameToken xmlns:ns0="http://test_ns.com">
      <Username>__USERNAME__</Username>
      <Password>__PASSWORD__</Password>
      <Reference>__REFERENCE__</Reference>
    </ns0:UsernameToken>
  </Header>
</soap-env:Header>