Python:如何使用Twisted作为SUDS的传输方式?
我有一个基于Twisted的项目,该项目用于与网络设备进行通信,并且正在添加对API为SOAP的新供应商(Citrix
NetScaler)的支持。不幸的是,Twisted中对SOAP的支持仍然依赖SOAPpy
,这已经严重过时了。实际上,就这个问题(我刚刚检查过)而言,twisted.web.soap
它甚至在21个月内都没有更新!
我想问一下是否有人愿意与Twisted一起使用SUDS的Twisted出色的异步传输功能来分享经验。在SUDS’中插入自定义Twisted运输工具似乎是很自然的选择Client.options.transport
,我只是很难把它包裹住。
我确实想出了一种通过利用来用SUDS异步调用SOAP方法的方法twisted.internet.threads.deferToThread()
,但是对我来说,这感觉像是一种hack。
这是我所做的一个示例,旨在为您提供一个想法:
# 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()
这可以按预期工作,并且将api.login()
呼叫延迟返回,直到完成为止,而不是阻塞。但是,正如我所说,这并不对劲。
在此先感谢您提供的任何帮助,指导,反馈,批评,侮辱或整体解决方案。
更新: 我发现的唯一解决方案是twisted-suds,它是经过修改以与Twisted一起使用的Suds的一个分支。
-
在Twisted上下文中对 传输
的默认解释可能是的实现twisted.internet.interfaces.ITransport
。在这一层,您基本上要处理通过某种套接字发送和接收的原始字节(UDP,TCP和SSL是最常用的三种)。这并不是SUDS
/
Twisted集成库真正感兴趣的。相反,您需要的是一个HTTP客户端,SUDS可以使用该HTTP客户端发出必要的请求,并显示所有响应数据,以便SUDS可以确定结果是什么是。也就是说,SUDS并不真正在乎网络上的原始字节。它关心的是HTTP请求和响应。如果检查
twisted.web.soap.Proxy
Twisted Web SOAP
API的客户端部分的实现,您会发现它实际上并没有做什么用。这是约20行代码胶水SOAPpy
来twisted.web.client.getPage
。也就是说,它就是按照我上面描述的方式将SOAPpy连接到Twisted的。理想的情况下,泡沫会提供某种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 Client提供第三段代码,并让它们协调交互。
但是,通过创建基于Twisted的SUDS传输(又称为HTTP客户端)来使事情工作并非 不可能
。Twisted主要使用Deferred
(也称为回调)公开事件的事实并不意味着这是它 唯一的
工作方式。通过使用第三方库(例如)greenlet
,可以提供基于协程的API,其中对异步操作的请求涉及将执行从一个协程切换到另一个协程,并且通过切换回原始协程来传递事件。有一个名为corotwine的项目可以做到这一点。它
可能
可以使用它为SUDS提供所需的HTTP客户端API;但是,不能保证。这取决于在上下文开关突然插入以前没有的情况下SUDS不会中断。这是SUDS的非常微妙和脆弱的属性,在以后的发行版中,SUDS开发人员可以轻松地(甚至无意间)对其进行更改,因此,即使您现在就可以使它工作,它也不是
理想的 解决方案(除非您可以从SUDS维护者那里获得合作,形式是承诺以这种配置测试他们的代码以确保其继续工作。顺便说一句,Twisted
Web的SOAP支持仍基于SOAPpy且近两年未进行修改的原因是,目前还没有明显的替代SOAPpy。有许多竞争者(Python有哪些SOAP客户端库,它们的文档在哪里?涵盖了其中的几个)。如果一切顺利,尝试更新Twisted的内置SOAP支持可能很有意义。在那之前,我认为单独进行这些集成库比较有意义,因此可以更轻松地对其进行更新,因此Twisted本身不会产生很多人都不希望的不同SOAP集成(这
会 比在目前的情况下,只有一个SOAP集成模块是没人想要的)。