【问题标题】:How to create soap header with Python suds library?如何使用 Python suds 库创建肥皂头?
【发布时间】:2015-09-01 17:00:47
【问题描述】:

我需要使用如下消息调用 SOAP 服务:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sub="https://secure.xpslogic.com/service/wijnen/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>

我有一些 php 示例代码,它将标题设置如下(并且效果很好):

auth = 数组(); $auth['token'] = 'xxx'; 如果 ($auth) { // 添加认证头 $this->clients[$module]->__setSoapHeaders( 新的肥皂头( $命名空间, '认证', $认证 ) ); }

我现在使用Python suds lib 构造(空)正文和标题,如下所示:

from suds.client import Client
from suds import WebFault

client = Client(url='https://example.com/sub.wsdl')

auth = client.factory.create('auth')
auth.token = 'xxx'
client.set_options(soapheaders=auth)

customerLogosPull = client.factory.create('customer_logos_pull')
result = client.service.customer_logos_pull(customerLogosPull)

但这给了我一个not well-formed (invalid token) 消息。打开日志记录时,我发现这是消息:

DEBUG:suds.mx.core:processing:
(Content){
   tag = "auth"
   value =
      (auth){
         token = "xxx"
         user_id = None
         user_token = None
      }
   type = <Element:0x10ff8c950 name="auth">
   <Complex:0x10ff8cbd0>
      <Sequence:0x10ff8cc50>
         <Element:0x10ff8cd10 name="token" type="(u'string', u'http://www.w3.org/2001/XMLSchema')" />
         <Element:0x10ff8cd50 name="user_id" type="(u'string', u'http://www.w3.org/2001/XMLSchema')" />
         <Element:0x10ff8cd90 name="user_token" type="(u'string', u'http://www.w3.org/2001/XMLSchema')" />
      </Sequence>
   </Complex>
</Element>
 }

对我来说它看起来不错,但它也给出了not well-formed (invalid token)。看到suds docs has 3 examples 关于如何传入soap headers,我也尝试了其他两个:

>>> token = client.factory.create('auth.token')
>>> token.set(TOKEN)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: token instance has no attribute 'set'

>>> client.set_options(soapheaders={'auth': {'token': 'xxx'}})
>>> customerLogosPull = client.factory.create('customer_logos_pull')
>>> result = client.service.customer_logos_pull(customerLogosPull)

在日志中给出了这个内容,仍然是not well-formed (invalid token)

(Content){
   tag = "auth"
   value =
      {
         token = "xxx"
      }
   type = <Element:0x106049290 name="auth">
   <Complex:0x106049510>
      <Sequence:0x106049590>
         <Element:0x106049650 name="token" type="(u'string', u'http://www.w3.org/2001/XMLSchema')" />
         <Element:0x106049690 name="user_id" type="(u'string', u'http://www.w3.org/2001/XMLSchema')" />
         <Element:0x1060496d0 name="user_token" type="(u'string', u'http://www.w3.org/2001/XMLSchema')" />
      </Sequence>
   </Complex>
</Element>
 }

有人知道如何使用 Python 在标头中正确设置令牌吗?欢迎所有提示!

【问题讨论】:

  • 您是如何获取日志来为您格式化日志的?
  • 如果需要设置多个soap header,见my answer here

标签: python soap header wsdl suds


【解决方案1】:

我的肥皂标题工作如下:

from suds.sax.element import Element
ssnp = Element("xsi:SessionHeader").append(Element('xsi:sessionId').setText("xxxxxxx"))
client.set_options(soapheaders=ssnp)

对应soap请求xml中如下所示的soapHeaders

<SOAP-ENV:Header>
  <xsi:SessionHeader>
     <xsi:sessionId>xxxxxxx</xsi:sessionId>
  </xsi:SessionHeader>
</SOAP-ENV:Header>

我们可以看到使用print client.last_sent()发送了什么请求

【讨论】:

    【解决方案2】:

    我试试

    from suds.client import Client
    WSDL_URL='http://apitest.comune.genova.it:28280/MANU_WSManutenzioni_MOGE/'
    
    #Create the Client:
    print("Print 1")
    client = Client(url=WSDL_URL)
    
    print("Print 2")
    from suds.sax.element import Element
    ssnp = Element("xsi:SessionHeader").append(Element('xsi:Authorization').setText("XXXXXXXXXXX"))
    client.set_options(soapheaders=ssnp)
    

    但我遇到了以下行的错误

    client = Client(url=WSDL_URL) 
    

    这里的错误:

    Traceback (most recent call last):
      File "/usr/local/lib/python3.6/site-packages/suds/transport/http.py", line 67, in open
        return self.u2open(u2request)
      File "/usr/local/lib/python3.6/site-packages/suds/transport/http.py", line 132, in u2open
        return url.open(u2request, timeout=tm)
      File "/usr/lib64/python3.6/urllib/request.py", line 532, in open
        response = meth(req, response)
      File "/usr/lib64/python3.6/urllib/request.py", line 642, in http_response
        'http', request, response, code, msg, hdrs)
      File "/usr/lib64/python3.6/urllib/request.py", line 570, in error
        return self._call_chain(*args)
      File "/usr/lib64/python3.6/urllib/request.py", line 504, in _call_chain
        result = func(*args)
      File "/usr/lib64/python3.6/urllib/request.py", line 650, in http_error_default
        raise HTTPError(req.full_url, code, msg, hdrs, fp)
    urllib.error.HTTPError: HTTP Error 405: Method Not Allowed
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "test_ws.py", line 44, in <module>
        client = Client(url=WSDL_URL)
      File "/usr/local/lib/python3.6/site-packages/suds/client.py", line 115, in __init__
        self.wsdl = reader.open(url)
      File "/usr/local/lib/python3.6/site-packages/suds/reader.py", line 151, in open
        d = self.fn(url, self.options)
      File "/usr/local/lib/python3.6/site-packages/suds/wsdl.py", line 136, in __init__
        d = reader.open(url)
      File "/usr/local/lib/python3.6/site-packages/suds/reader.py", line 78, in open
        d = self.download(url)
      File "/usr/local/lib/python3.6/site-packages/suds/reader.py", line 94, in download
        fp = self.options.transport.open(Request(url))
      File "/usr/local/lib/python3.6/site-packages/suds/transport/https.py", line 62, in open
        return HttpTransport.open(self, request)
      File "/usr/local/lib/python3.6/site-packages/suds/transport/http.py", line 69, in open
        raise TransportError(str(e), e.code, e.fp)
    suds.transport.TransportError: HTTP Error 405: Method Not Allowed
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-19
      相关资源
      最近更新 更多