【问题标题】:Benefits of twisted-suds - Async way of using python suds soap libtwisted-suds 的好处 - 使用 python suds soap lib 的异步方式
【发布时间】:2013-11-03 09:11:23
【问题描述】:

我正在使用 python suds 库来创建基于本地 wsdl 文件的 SOAP 客户端。我的目标是使用 Twisted 作为后端,所以我以异步方式查询 SOAP 服务器。

我知道这个话题已经讨论过不同的时间了(here1here2),但我还有一些问题。


我见过三种不同的方法来使用twisted with suds:

a) 将此 patch 应用于 suds 库。

b) 使用twisted-suds,它是泡沫的一个分支。

c) 受this post 的影响,我使用扭曲的deferToThread 操作实现了Client_Async suds 客户端,(可以找到here 的完整工作要点。我还实现了一个Client_Sync suds 客户端)一些基准)

# Init approach c) code
from suds.client import Client as SudsClient
from twisted.internet.threads import deferToThread

class MyClient(SudsClient):
   def handleFailure(self, f, key, stats):
        stats.stop_stamp(error=True)
        logging.error("%s. Failure: %s" % (key, str(f)))

    def handleResult(self, result, key, stats):
        stats.stop_stamp(error=False)
        success, text, res = False, None, None
        try:
            success = result.MessageResult.MessageResultCode == 200
            text = result.MessageResult.MessageResultText
            res = result.FooBar
        except Exception, err:
            pass
        logging.debug('%40s : %5s %10s \"%40s\"' % (key, success, text, res))
        logging.debug('%40s : %s' % (key, self.last_sent()))
        logging.debug('%40s : %s' % (key, self.last_received()))

def call(stats, method, service, key, *a, **kw):
    stats.start_stamp()
    logging.debug('%40s : calling!' % (key))
    result = service.__getattr__(method)(*a, **kw)
    return result

class Client_Async(MyClient):
    """ Twisted based async client"""
    def callRemote(self, stats, method, key, *args, **kwargs):
        logging.debug('%s. deferring to thread...' % key)
        d = deferToThread(call, stats, method, self.service, key, *args, **kwargs)
        d.addCallback(self.handleResult, key, stats)
        d.addErrback(self.handleFailure, key, stats)
        return d

class Client_Sync(MyClient):
    def callRemote(self, stats,  method, key, *args, **kwargs):
        result = None
        try:
            result = call(stats, method, self.service, key, *args, **kwargs)
        except Exception, err:
            self.handleFailure(err, key, stats)
        else:
            self.handleResult(result, key, stats)
# End approach c) code

使用 c) 方法做一个小型基准测试指出了异步模型的好处:

-- Sync model using Client_Sync of approach c).
# python soap_suds_client.py -t 200 --sync
Total requests:800/800. Success:794 Errors:6
Seconds elapsed:482.0
Threads used:1

-- Async model using Client_Async of approach c).
# python soap_suds_client.py -t 200
Total requests:800/800. Success:790 Errors:10
Seconds elapsed:53.0
Threads used:11

我还没有测试过 a) 或 b) 方法,我的问题是:

除了使用一个线程之外,我真正从它们那里获得了什么?

【问题讨论】:

    标签: python soap asynchronous twisted suds


    【解决方案1】:

    我在我的项目中使用肥皂水。我不需要做任何补丁,也不需要使用扭曲的泡沫。 我正在使用 0.4.1-2 版本的 python-suds 包(在 ubuntu 上),它带有非常有用的 nosend 选项。

        # This parses the wsdl file. The autoblend option you'd probably skip, 
        # its needed when name spaces are not strictly preserved (case for Echo Sign).
        from suds import client
        self._suds = client.Client('file://' + config.wsdl_path, nosend=True,
                                   autoblend=True)
    
        ....
    
        # Create a context for the call, example sendDocument() call. This doesn't yet
        # send anything, only creates an object with the request and capable of parsing
        # the response
        context = self._suds.service.sendDocument(apiKey=....)
    
        # Actually send the request. Use any web client you want. I actually use 
        # something more sophisticated, but below I put the example using 
        # standard twisted web client.
        from twisted.web import client
        d = client.getPage(url=context.client.location(), 
                           postdata=str(context.envelope),
                           method='POST',
                           headers=context.client.headers())
    
        # The callback() of the above Deferred is fired with the body of the 
        # http response. I parse it using the context object.          
        d.addCallback(context.succeeded)
    
        # Now in the callback you have the actual python object defined in 
        # your WSDL file. You can print...
        from pprint import pprint
        d.addCallback(pprint)
        # I the response is a failure, your Deferred would be errbacked with 
        # the suds.WebFault exception.
    

    【讨论】:

    • 是否需要 v0.4.1-2? nosend 选项似乎出现在 0.4 fedorahosted.org/suds/wiki/Documentation#OPTIONS
    • 我不得不承认,我还没有测试过任何其他版本。我只是想给出一个具体的答案,指向我确定它可以工作的版本。
    猜你喜欢
    • 1970-01-01
    • 2011-02-09
    • 2016-03-20
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多