python suds 一坑


當被調用服務的返回xml內容是按照wsdl文件描述定義的, 就莫名奇妙返回suds.WebFault

沒有更多詳細信息!

 

於是將源碼解壓,並插入到sys.path[0], 通過設置斷點的方式找出非標准的返回報文到底在說啥。從而調整對應參數。

suds-0.4/suds/bindings/binding.py (246~268)

    def get_fault(self, reply):
        """
        Extract the fault from the specified soap reply.  If I{faults} is True, an
        exception is raised.  Otherwise, the I{unmarshalled} fault L{Object} is
        returned.  This method is called when the server raises a I{web fault}.
        @param reply: A soap reply message.
        @type reply: str
        @return: A fault object.
        @rtype: tuple ( L{Element}, L{Object} )
        """
        import pdb
        pdb.set_trace()
        reply = self.replyfilter(reply)
        sax = Parser()
        faultroot = sax.parse(string=reply)
        soapenv = faultroot.getChild('Envelope')
        soapbody = soapenv.getChild('Body')
        fault = soapbody.getChild('Fault')
        unmarshaller = self.unmarshaller(False)
        p = unmarshaller.process(fault)
        if self.options().faults:
            raise WebFault(p, faultroot)
        return (faultroot, p.detail)

 

順便記錄下suds神器的基本用法,方便查閱:

1. 查看服務接口

import suds
client=suds.client.Client('xxxx_webservice_url')
def get_all_methods(client):
    return [method for method in client.wsdl.services[0].ports[0].methods]

 

2. 查看某個具體接口的傳輸參數及類型

def get_method_args(client, method_name):
    method = client.wsdl.services[0].ports[0].methods[method_name]
    input_params = method.binding.input
    return input_params.param_defs(method)

 

3. 調用接口服務

client.service.xxx_function(....)

 

4. 關於調試

輸出之前調用服務接口時發送了什么soap報文,以及收到什么樣的soap報文

print 'last sent:\n', client.last_sent()
print 'last recv:\n', client.last_received()

 當服務器返回報文格式不規范時(非wsdl中定義的),client.last_received()為None。這個時候顯然對聯調極為不利。

 那就利用suds自身的日志記錄看看咯。設定如下:

import sys
import logging logger
= logging.getLogger('suds') logger.setLevel(logging.DEBUG) logger.addHandler(logging.StreamHandler(sys.stdout))

如果只關心傳輸了什么,則可以限定logger為“suds.transport.http“

import sys
logger = logging.getLogger('suds.transport.http')
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler(sys.stdout))

 5. 異常的捕捉和輸出

try:
    client.service.xxx_func(*args, **kwargs)
except suds.WebFault,ex:
    print ex.fault        
    print ex.document

 

 

 

后記:對於第三方庫莫名其妙的問題,果斷及時拿源碼過來剖析(至少debug)

 

DEMO

 來個demo說明如何運用,如下:

>>> import suds
>>> url='http://www.gpsso.com/webservice/kuaidi/kuaidi.asmx?wsdl'
>>> client = suds.client.Client(url)
>>> print get_all_methods(client)
[KuaidiQuery]
>>> print get_method_args(client, 'KuaidiQuery')
[(Compay, <Element:0x7f6c55bc43d0 name="Compay" type="(u'string', u'http://www.w3.org/2001/XMLSchema')" />), (OrderNo, <Element:0x7f6c55bc4450 name="OrderNo" type="(u'string', u'http://www.w3.org/2001/XMLSchema')" />)]
>>> print client.service.KuaidiQuery(Company='EMS', OrderNo='1111')
(KuaidiQueryResult){
   API = 
      (API){
         RESULTS = "0"
         MESSAGE = "接口查詢成功"
      }
 }
>>> print client.last_sent()
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://gpsso.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <ns0:Body>
      <ns1:KuaidiQuery>
         <ns1:OrderNo>1111</ns1:OrderNo>
      </ns1:KuaidiQuery>
   </ns0:Body>
</SOAP-ENV:Envelope>
>>> print client.last_received()
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope>
   <soap:Body>
      <KuaidiQueryResponse xmlns="http://gpsso.com/">
         <KuaidiQueryResult>
            <API>
               <RESULTS>0</RESULTS>
               <MESSAGE>接口查詢成功</MESSAGE>
            </API>
         </KuaidiQueryResult>
      </KuaidiQueryResponse>
   </soap:Body>
</soap:Envelope>

 

轉載請注明本文來源:http://www.cnblogs.com/Tommy-Yu/p/5567091.html

謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM