jat*_*ism 12 python soap twisted suds transport
我有一个基于Twisted的项目,用于与网络设备通信,我正在添加对API为SOAP 的新供应商(Citrix NetScaler)的支持.不幸的是,Twisted中对SOAP的支持依然存在SOAPpy
,这已经过时了.事实上,就这个问题(我刚检查过)而言,twisted.web.soap
本身在21个月内甚至没有更新!
我想问一下,如果有人有任何经验,他们愿意与SUDS使用Twisted的超级异步传输功能.看起来插入一个自定义的Twisted传输将是一个自然的SUDS' Client.options.transport
,我只是很难缠绕我的头.
我确实想出了一种方法,通过利用异步方式使用SUDS调用SOAP方法twisted.internet.threads.deferToThread()
,但这对我来说就像是一个黑客.
这是我做过的一个例子,给你一个想法:
# netscaler is a module I wrote using suds to interface with NetScaler SOAP
# Source: http://bitbucket.org/jathanism/netscaler-api/src
import netscaler
import os
import sys
from twisted.internet import reactor, defer, threads
# netscaler.API is the class that sets up the suds.client.Client object
host = 'netscaler.local'
username = password = 'nsroot'
wsdl_url = 'file://' + os.path.join(os.getcwd(), 'NSUserAdmin.wsdl')
api = netscaler.API(host, username=username, password=password, wsdl_url=wsdl_url)
results = []
errors = []
def handleResult(result):
print '\tgot result: %s' % (result,)
results.append(result)
def handleError(err):
sys.stderr.write('\tgot failure: %s' % (err,))
errors.append(err)
# this converts the api.login() call to a Twisted thread.
# api.login() should return True and is is equivalent to:
# api.service.login(username=self.username, password=self.password)
deferred = threads.deferToThread(api.login)
deferred.addCallbacks(handleResult, handleError)
reactor.run()
Run Code Online (Sandbox Code Playgroud)
这可以按预期工作,并推迟api.login()
调用返回直到完成,而不是阻塞.但正如我所说,感觉不对.
提前感谢任何帮助,指导,反馈,批评,侮辱或整体解决方案.
更新:我发现的唯一解决方案是twisted-suds,这是一个经过修改以与Twisted一起使用的Suds的分支.
Jea*_*one 13
Twisted上下文中对传输的默认解释可能是一个实现twisted.internet.interfaces.ITransport
.在这一层,你基本上处理的是通过某种类型的套接字发送和接收的原始字节(UDP,TCP和SSL是最常用的三种).这并不是SUDS/Twisted集成库所关注的.相反,你想要的是一个HTTP客户端,SUDS可以使用它来发出必要的请求,并提供所有响应数据,以便SUDS可以确定结果是.也就是说,SUDS并不真正关心网络上的原始字节.它关心的是HTTP请求和响应.
如果你检查twisted.web.soap.Proxy
(Twisted Web SOAP API的客户端部分)的实现,你会发现它并没有真正做太多.这是关于20的该胶合代码行SOAPpy
来twisted.web.client.getPage
.也就是说,它正如我上面描述的那样将SOAPpy挂钩到Twisted.
理想情况下,SUDS会提供某种类型的API SOAPpy.buildSOAP
和SOAPpy.parseSOAPRPC
(可能API会更复杂,或者接受更多参数 - 我不是SOAP专家,所以我不知道SOAPpy的特定API缺少重要的东西 - 但基本的想法应该是相同的).然后你可以写一些twisted.web.soap.Proxy
基于SUDS的东西.如果twisted.web.client.getPage
没有提供对请求的足够控制或有关响应的足够信息,您也可以使用twisted.web.client.Agent
,这是最近引入的,并提供对整个请求/响应过程的更多控制.但同样,这与getPage
基于当前的代码完全相同,只是一种更灵活/更具表现力的实现.
刚看了API文档Client.options.transport
,听起来像SUDS传输基本上是一个HTTP客户端.这种集成的问题是SUDS想要发送请求然后能够立即得到响应.由于Twisted主要基于回调,因此基于Twisted的HTTP客户端API无法立即返回对SUDS的响应.它只能返回Deferred
(或等效).
这就是为什么如果关系倒置,事情会更好.不要给SUDS提供HTTP客户端,而是将SUDS和HTTP客户端提供给第三段代码,让它协调交互.
但是,通过创建基于Twisted的SUDS传输(也称为HTTP客户端),可能并非不可能.Twisted主要使用Deferred
(也就是回调)来暴露事件的事实并不意味着这是它可以工作的唯一方式.通过使用第三方库greenlet
,可以提供基于协程的API,其中异步操作的请求涉及将执行从一个协程切换到另一个协程,并且通过切换回原始协程来传递事件.有一个名为corotwine的项目可以做到这一点.它可能有可能利用这一特性提供的那种就是了HTTP客户端API的肥皂水; 但是,它不能保证.它取决于SUDS在突然插入上下文切换时没有断开,而之前没有.这是SUDS的一个非常微妙和脆弱的属性,SUDS开发人员可以在将来的版本中轻松地(无意中,甚至)更改,所以它可能不是理想的解决方案,即使你现在可以让它工作(除非你能以承诺的形式获得SUDS维护者的合作,以便在这种配置中测试他们的代码,以确保它继续工作).
另外,Twisted Web的SOAP支持仍然基于SOAPpy并且近两年未被修改的原因是没有明确替代SOAPpy.有很多竞争者(Python存在哪些SOAP客户端库,它们的文档在哪里?涵盖了其中的几个).如果事情安定下来,尝试更新Twisted的内置SOAP支持可能是有意义的.在那之前,我认为它更有意义单独做这些集成库,让他们可以更容易地更新,如此扭曲本身不具有不同的SOAP集成的一大堆,没有人愿意(这最终将是有过之而无不及目前的情况,只有一个没有人想要的SOAP集成模块.