【问题标题】:Python, suds - dealing with rotten WSDL caches and responsesPython, suds - 处理腐烂的 WSDL 缓存和响应
【发布时间】:2014-05-08 16:22:27
【问题描述】:

在过去的几天里,我一直在用头撞一个愚蠢的 SOAP 服务器。

在我的错误日志中,我收到了一个如下所示的异常/跟踪日志:“异常:(Widget, None, ), must be qref” -- (关键短语是“must be qref”) .

首先,我发现我们的缓存已损坏。所以我禁用了缓存,但问题仍然存在。

其次,我发现这确实是服务器的错,没有随机地给我一个正确的 WSDL;特别是在使用多个工作实例时。新闻快讯 - 我的服务器操作员联系人在他的日志中确认“服务器太忙”错误。 “神奇宝贝!”显然,当服务器本应提供 HTTP 503 时,它会重定向到 HTTP 200 页面。

我想知道如何更优雅地处理这些令人惊讶的不良行为,实际上我想出了一个有用的、相当通用的解决方案。在此处发布以供将来参考。

【问题讨论】:

    标签: python soap soap-client suds


    【解决方案1】:

    类似这样的:

    from suds.client import Client
    from suds.transport.https import HttpAuthenticated
    from suds.xsd.doctor import ImportDoctor, Import
    import os
    import shutil
    import time
    from tempfile import gettempdir as tmp
    
    class MyTransport(HttpAuthenticated):
        def __init__(self,*args,**kwargs):
            HttpAuthenticated.__init__(self,*args,**kwargs)
            self.last_headers = None
        def send(self,request):
            result = HttpAuthenticated.send(self,request)
            self.last_headers = result.headers
            return result
    
    class TenaciousConnector():
        def init_client(self, wsdl_url):
            retries = 3
            services = None
            # Cached mode
            (client, services) = self._init_client(wsdl_url)
            while not services and retries > 0:
                nap_time = 6 - retries
                retries = retries - 1
                time.sleep(nap_time)
                # clear potentially rotten cache right before retrying
                shutil.rmtree(os.path.join(tmp(), 'suds'), True)
                (client, services) = self._init_client(wsdl_url)
            if not services:
                # No-cache mode
                retries = 3
                (client, services) = self._init_client(wsdl_url, False)
                while not services and retries > 0:
                    nap_time = 6 - retries
                    retries = retries - 1
                    time.sleep(nap_time)
                    (client, services) = self._init_client(wsdl_url, False)
            if not services:
                raise Exception("Failed at loading WSDL from {0}".format(wsdl_url))
            return client
    
        def _init_client(self, wsdl_url, cache=True):
            i_doc = ImportDoctor(Import('http://schemas.xmlsoap.org/soap/encoding/'))
            tx = MyTransport()
            if cache:
                client = Client(wsdl_url, doctor=i_doc, transport=tx)
            else:
                client = Client(wsdl_url, doctor=i_doc, transport=tx, cache=None)
            services = client.wsdl.services
            return (client, services)
    

    类似这样的使用:

    connector = TenaciousConnector()
    client = connector.init_client("http://example.com/webservice/wsdl")
    client.factory.create('Widget')
    

    【讨论】:

      猜你喜欢
      • 2015-01-16
      • 1970-01-01
      • 1970-01-01
      • 2022-08-16
      • 2013-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多