【问题标题】:Why can't I set SOAP headers in pysimplesoap?为什么我不能在 pysimplesoap 中设置 SOAP 标头?
【发布时间】:2015-06-01 19:19:31
【问题描述】:

我收到了一些用于调用 SOAP 服务的示例 php 代码,我现在需要将其转换为 Python。在 php 代码中,他们将标题设置如下:

$auth = array();
$auth['token'] = 'xxx';
if ($auth) {
    // add auth header
    $this->clients[$module]->__setSoapHeaders(
        new SoapHeader(
            $namespace, 
            'auth', 
            $auth
        )
    );
}

所以auth 标头应如下所示:['token' => 'xxx']。然后我将 wsdl 加载到 SoapUI,这给了我以下示例 xml:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sub="https://example.com/path/to/sub">
   <soapenv:Header>
      <sub:auth>
         <token>?</token>
         <!--Optional:-->
         <user_id>?</user_id>
         <!--Optional:-->
         <user_token>?</user_token>
      </sub:auth>
   </soapenv:Header>
   <soapenv:Body>
      <sub:customer_logos_pull>
         <!--Optional:-->
         <language>?</language>
         <!--Optional:-->
         <limit>?</limit>
         <!--Optional:-->
         <options_utc>?</options_utc>
      </sub:customer_logos_pull>
   </soapenv:Body>
</soapenv:Envelope>

在 pysimplesoap 中,我现在尝试这样的事情:

from pysimplesoap.client import SoapClient

WSDL = 'https://example.com/some/path/sub.wsdl'
TOKEN = 'xxx'

client = SoapClient(wsdl=WSDL, trace=True)
client['auth'] = {'token': TOKEN}
print client.customer_logos_pull({})

但我收到一条错误消息 ExpatError: not well-formed (invalid token): line 1, column 0,这是有道理的,因为在记录的 xml 中我看到标题为空:

<soap:Header/>

我尝试通过在auth 之前包含sub: 来改变代码,如下所示:client['sub:auth'] = {'token': TOKEN},但我得到了同样的错误。

有人知道我在这里做错了什么吗?欢迎所有提示!

【问题讨论】:

  • 它必须使用pysimplesoap - 它甚至无法安装,因为它有点坏了:/
  • @JamesMills - 它本身不需要是 pysimplesoap。我只需要让它工作。我也试过用肥皂水。但我也无法让它工作:stackoverflow.com/questions/30874988/… 我使用的库无关紧要,它只需要在 Python 中就可以了。你知道如何在不同的图书馆里做吗?

标签: python web-services soap wsdl


【解决方案1】:

所以我认为我们可以通过使用suds解决这个问题。

这是一个非常基本的示例,说明如何发送包含标头的 SOAP 请求:

示例:

from suds.sax.element import Element 

client = client(url) 
ssnns = ('ssn', 'http://namespaces/sessionid') 
ssn = Element('SessionID', ns=ssnns).setText('123') 
client.set_options(soapheaders=ssn)  
result = client.service.addPerson(person)

这是一个如何发送以下标头的示例:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP ENC="http://www.w3.org/2003/05/soap-encoding">
    <ssn:SessionID SOAP-ENV:mustUnderstand="true">123</ssn:SessionID>
 </SOAP-ENV:Header>

NB:我实际上并没有尝试过,因为我无法访问任何我可以测试的现成的 SOAP/XML 服务! p>

因此,在您的特定示例中,您将执行以下操作:

>>> from suds.sax.element import Element
>>> subns = ("sub", "http://namespaces/sub")
>>> sub = Element("auth", ns=subns)
>>> token = Element("token").setText("?")
>>> user_id = Element("user_id").setText("?")
>>> user_token = Element("user_token").setText("?")
>>> sub.append(token)
Element (prefix=sub, name=auth)
>>> sub.append(user_id)
Element (prefix=sub, name=auth)
>>> sub.append(user_token)
Element (prefix=sub, name=auth)
>>> print(sub.str())
<sub:auth xmlns:sub="http://namespaces/sub">
   <token>?</token>
   <user_id>?</user_id>
   <user_token>?</user_token>
</sub:auth>

然后在您的client 对象上调用set_options()

client.set_options(soapheaders=sub)

您可以轻松通过运行使用pip 安装suds

$ pip install suds

【讨论】:

    猜你喜欢
    • 2018-11-22
    • 2012-12-26
    • 2019-09-12
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    • 2010-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多