Python:如何使用Twisted作为SUD的传输?

Python:如何使用Twisted作为SUD的传输?,python,soap,twisted,suds,transport,Python,Soap,Twisted,Suds,Transport,我有一个基于Twisted的项目 与网络设备通信,我正在添加对新 API为SOAP的供应商()。不幸的是 Twisted中对SOAP的支持仍然依赖于SOAPpy,这一点非常糟糕 日期。事实上,在这个问题上(我刚刚检查过), 它本身已经21个月没有更新了 我想问一下,是否有人有任何经验,他们愿意 利用Twisted卓越的异步传输 功能与肥皂水。这看起来像是插入了一个自定义的扭曲 运输将是一个自然适合在肥皂水'客户端。选项。运输,我只是有 很难让我的头围绕着它 我确实想出了一种用肥皂水调用SOAP方

我有一个基于Twisted的项目 与网络设备通信,我正在添加对新 API为SOAP的供应商()。不幸的是 Twisted中对SOAP的支持仍然依赖于
SOAPpy
,这一点非常糟糕 日期。事实上,在这个问题上(我刚刚检查过), 它本身已经21个月没有更新了

我想问一下,是否有人有任何经验,他们愿意 利用Twisted卓越的异步传输 功能与肥皂水。这看起来像是插入了一个自定义的扭曲 运输将是一个自然适合在肥皂水'客户端。选项。运输,我只是有 很难让我的头围绕着它

我确实想出了一种用肥皂水调用SOAP方法的方法 通过使用twisted.internet.threads.DeferrotThread()异步执行, 但这对我来说像是一种恶作剧

下面是我所做工作的一个例子,给你一个想法:

# 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的肥皂水。

Twisted上下文中传输的默认解释可能是Twisted.internet.interfaces.ITransport的实现。在这一层,您基本上要处理通过某种套接字发送和接收的原始字节(UDP、TCP和SSL是最常用的三种)。这并不是SUDS/Twisted集成库真正感兴趣的。相反,您需要的是一个HTTP客户端,SUD可以使用它来发出必要的请求,并提供所有响应数据,以便SUD可以确定结果是什么。也就是说,SUDS并不真正关心网络上的原始字节。它关心的是HTTP请求和响应

如果您检查
twisted.web.soap.Proxy
(twisted web soap API的客户机部分)的实现,您会发现它实际上做的不多。大约有20行代码将
SOAPpy
粘合到
twisted.web.client.getPage
。也就是说,它以我上面描述的方式将Soapy连接到Twisted

理想情况下,sud将提供某种类型的API,如
SOAPpy.buildSOAP
SOAPpy.parseSOAPRPC
(也许API会更复杂一些,或者接受更多的参数——我不是SOAP专家,所以我不知道SOAPpy的特定API是否遗漏了一些重要的东西——但基本思想应该是一样的)如果
twisted.web.client.getPage
不能提供对请求的足够控制或关于响应的足够信息,那么你也可以使用
twisted.web.soap.Proxy
,它是最近引入的,提供了很多或者控制整个请求/响应过程。但是,这与当前基于
getPage
的代码的思想是一样的,只是一种更灵活、更具表现力的实现

刚刚看了
Client.options.transport
的API文档,它听起来像是一个基本上是HTTP客户端的SUDS传输。这种集成的问题是,SUDS希望发送一个请求,然后能够立即得到响应。由于Twisted主要基于回调,因此Twisted基于HTTP c客户端API无法立即返回对SUD的响应。它只能返回延迟的
响应(或等效响应)

这就是为什么如果关系颠倒,事情会变得更好。与其给肥皂水一个HTTP客户端来玩,不如给肥皂水和HTTP客户端第三段代码,让它来协调交互

不过,通过创建基于Twisted的SUDS传输(也称为HTTP客户端)让事情正常运行并非不可能公开事件并不意味着这是唯一可行的方法。通过使用第三方库,如
greenlet
,可以提供基于协同路由的API,其中异步操作的请求涉及将执行从一个协同路由切换到另一个,事件通过切换回原始的协同路由来传递outine。有一个名为的项目可以做到这一点。可以使用它为sud提供它想要的那种HTTP客户端API;但是,这并不能保证。这取决于当上下文开关突然插入到以前没有的位置时,sud不会断开。这是sud的一个非常微妙和脆弱的属性,可以在未来的版本中,很容易被SUDS开发人员更改(甚至是无意更改),因此即使您现在就可以让它工作,它也可能不是理想的解决方案(除非您可以得到SUDS维护人员的合作,承诺在这种配置中测试他们的代码,以确保它继续工作)


顺便说一句,Twisted Web的SOAP支持仍然基于SOAPpy,并且在近两年内没有进行过修改,原因是没有明确的SOAPpy替代品出现。有很多竞争者(包括其中的几个)。如果情况稳定下来,尝试更新Twisted的内置SOAP支持可能是有意义的。在此之前,我认为将这些集成库分开进行更有意义,这样它们可以更容易地更新,这样Twisted本身就不会有一大堆没有人想要的不同SOAP集成(这比目前的情况更糟糕,因为只有一个SOAP集成模块,没有人想要)。

谢谢您深思熟虑的建议