【问题标题】:Python - Zeep SOAP Complex HeaderPython - Zeep SOAP 复杂标头
【发布时间】:2017-03-22 21:37:42
【问题描述】:

我想通过 zeep 库将“复杂”标头传递给 SOAP 服务

它应该是这样的

 <soapenv:Header>
      <something:myVar1>FOO</something:myVar1>
      <something:myVar2>JAM</something:myVar2>
 </soapenv:Header>

我猜我这样发送标头成功了

header = xsd.Element(
    '{http://urlofthews}Header',
        xsd.ComplexType([
        xsd.Element(
        '{http://urlofthews}myVar1',
        xsd.String()),
        xsd.Element(
        '{http://urlofthews}myVar2',
        xsd.String())
        ])
    )

header_value = header(myVar1='FOO',myVar2='JAM')
print (header_value)
datasoap=client.service.UserRessourcesCatalog(requete,_soapheaders=[header_value])

但我不知道如何使用 XSD 在我的 Header 中声明和传递命名空间“某物”。

有什么帮助吗?

提前致谢。

最好的问候


如文档中所述

http://docs.python-zeep.org/en/master/headers.html

“另一种选择是传递一个 lxml Element 对象。如果 wsdl 没有定义一个 soap 头但服务器确实期望它,这通常很有用。”

这是我的情况,所以我尝试了

try:
        import xml.etree.cElementTree as ET
    except ImportError:
        import xml.etree.ElementTree as ET
    ET.register_namespace('something', 'http://urlofthews')

    headerXML = ET.Element("soapenv:Header")
    var1 = ET.SubElement(headerXML, "something:myVar1")
    var1.text = "FOO"
    var2 = ET.SubElement(headerXML, "something:myVar2")
    var2.text = "JAM"


headerDict=xmltodict.parse(ET.tostring(headerXML))
print (json.dumps(headerDict))

    datasoap=client.service.UserRessourcesCatalog(requete,_soapheaders=headerDict)

但我得到:ComplexType() 得到了一个意外的关键字参数 u'soapenv:Header'。签名:``

【问题讨论】:

    标签: python-3.x soap zeep


    【解决方案1】:

    我最近遇到了这个问题,下面是我的解决方法。

    假设您有一个如下所示的“安全”标头...

    <env:Header>
    <Security>
        <UsernameToken>
            <Username>__USERNAME__</Username>
            <Password>__PWD__</Password>
        </UsernameToken>
        <ServiceAccessToken>        
            <AccessLicenseNumber>__KEY__</AccessLicenseNumber>
        </ServiceAccessToken>
    </Security>
    </env:Header>
    

    为了在 zeep 客户端的请求中发送此标头,您需要执行以下操作:

    header = zeep.xsd.Element(
                'Security',
                zeep.xsd.ComplexType([
                    zeep.xsd.Element(
                        'UsernameToken',
                        zeep.xsd.ComplexType([
                            zeep.xsd.Element('Username',zeep.xsd.String()),
                            zeep.xsd.Element('Password',zeep.xsd.String()),
                        ])
                    ),
                    zeep.xsd.Element(
                        'ServiceAccessToken',
                        zeep.xsd.ComplexType([
                            zeep.xsd.Element('AccessLicenseNumber',zeep.xsd.String()),
                        ])
                    ),
                ])
            )
    
    header_value = header(UsernameToken={'Username':'test_user','Password':'testing'},UPSServiceAccessToken={'AccessLicenseNumber':'test_pwd'})
    
    client.service.method_name_goes_here(
                        _soapheaders=[header_value],#other method data goes here
                    )
    

    【讨论】:

    • 谢谢你的解释遗忘
    • 不客气。由于它仍被标记为“zeep”问题,您是否有机会确认我的答案有效 - 所以您可以接受它?
    • 这个解决方案对我来说非常有效。非常感谢,没有关于使用 Zeep 的肥皂请求的复杂标头的示例。
    • 很高兴它帮助您解决了 SergioMP。
    • 如果规范不包含封装的“Security”元素并且“env:Header”只保留了“UsernameToken”和“ServiceAccessToken”,这将如何编写?是否就像移除外部的 zeep.xsd.Element 一样简单?我有一个类似的问题here
    【解决方案2】:

    感谢 Oblivion02。

    我终于用原始方法了

    headers = {'content-type': 'text/xml'}
    body = """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://blablabla">
    <soapenv:Header>
    <something:myVar1>FOO</something:myVar1>
    <something:myVar2>JAM</something:myVar2>
    </soapenv:Header>
    <soapenv:Body>
              ...
    </soapenv:Body>
    </soapenv:Envelope>"""
    
    response = requests.post(wsdl,data=body,headers=headers)
    

    【讨论】:

    • 你认为你能接受我的回答吗?该问题仍被标记为 zeep 问题 - 因此,虽然您的答案使用原始方法有效 - 我提供的答案使用 zeep 库。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多