[英]Benefits of twisted-suds - Async way of using python suds soap lib
I'm using python suds library to make a SOAP client based on a local wsdl file. 我正在使用python suds库来创建基于本地wsdl文件的SOAP客户端。 My goal is to use Twisted as the backend so I query the SOAP servers in a asyncronous way.
我的目标是使用Twisted作为后端,因此我以异步方式查询SOAP服务器。
I know this topic has been covered different times ( here1 , here2 ), but I still have some questions. 我知道这个主题已被覆盖不同的时间( here1 , here2 ),但我仍然有一些问题。
I've seen three different approaches to use twisted with suds: 我已经看到三种不同的方法来使用与肥皂混合:
a) Applying this patch to the suds library. a)将此补丁应用于suds库。
b) Use twisted-suds , which is a fork of suds. b)使用tw-suds ,这是肥皂水。
c) Influenced by this post , I implemented Client_Async
suds client using the twisted deferToThread
operation, (fully working gist can be found here . I also implemented a Client_Sync
suds client as well to do some benchmarks) c)受到这篇文章的影响,我使用twisted
deferToThread
操作实现了Client_Async
客户端(可以在这里找到完全工作的gist。我还实现了Client_Sync
客户端以做一些基准测试)
# 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
Doing a small benchmark using the c) approach points the benefits of the Async model: 使用c)方法做一个小基准测试指出了Async模型的好处:
-- 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
I haven't tested approaches a) or b), my question is: 我没有测试方法a)或b),我的问题是:
What am I really gaining from them apart from the use of just one thread? 除了使用一个线程之外,我真正从中获得了什么?
I'm using suds in my projects. 我在我的项目中使用肥皂水。 I didn't have to do any patches, or use twisted-suds.
我没有做任何补丁,也没有使用过扭曲的泡沫。 I'm using the 0.4.1-2 version of python-suds package (on ubuntu) and it comes with very usefull nosend option.
我正在使用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.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.