Python,SUD-处理腐烂的WSDL缓存和响应

Python,SUD-处理腐烂的WSDL缓存和响应,python,soap,soap-client,suds,Python,Soap,Soap Client,Suds,在过去的几天里,我一直在与一个愚蠢的SOAP服务器进行碰撞 在我的错误日志中,我得到一个异常/tracelog,如下所示:“异常:(Widget,None,)必须是qref”--(关键短语是“必须是qref”) 首先,我发现我们有一个腐烂的缓存。所以我禁用了缓存,但问题仍然存在 第二,我发现这确实是服务器的错,因为它没有随机地给我一个合适的WSDL;尤其是在使用多个辅助实例时。新闻快讯-我的服务器操作员联系人确认其日志中存在“服务器太忙”错误。“Wunderbar!”显然,服务器在应该提供HTT

在过去的几天里,我一直在与一个愚蠢的SOAP服务器进行碰撞

在我的错误日志中,我得到一个异常/tracelog,如下所示:“异常:(Widget,None,)必须是qref”--(关键短语是“必须是qref”)

首先,我发现我们有一个腐烂的缓存。所以我禁用了缓存,但问题仍然存在

第二,我发现这确实是服务器的错,因为它没有随机地给我一个合适的WSDL;尤其是在使用多个辅助实例时。新闻快讯-我的服务器操作员联系人确认其日志中存在“服务器太忙”错误。“Wunderbar!”显然,服务器在应该提供HTTP 503时重定向到HTTP 200页面

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

类似以下内容:

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')
像这样使用:

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')