我有一个基于 Twisted 的项目用于
与网络设备通信,我正在添加对新的支持
API 为 SOAP 的供应商 ( Citrix NetScaler )。不幸的是
Twisted 中对 SOAP 的支持仍然依赖于 SOAPpy ,这很糟糕
日期。事实上,从这个问题开始(我刚查过), twisted.web.soap
本身甚至在 21 个月内都没有更新!
我想问一下是否有人有任何经验他们愿意
与使用 Twisted 出色的异步传输共享
SUDS 的功能。似乎插入了自定义的 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()
api.login()打电话直到最佳答案
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 的想法是一样的。基于代码,只是一个更灵活/更具表现力的实现。
刚刚查看了 Client.options.transport 的 API 文档,听起来像 SUDS 传输基本上是一个 HTTP 客户端。这种集成的问题在于 SUDS 想要发送请求,然后能够立即获得响应。由于 Twisted 主要基于回调,因此基于 Twisted 的 HTTP 客户端 API 无法立即向 SUDS 返回响应。它只能返回 Deferred (或等价物)。
这就是为什么如果关系颠倒,事情会更好的原因。不是给 SUDS 一个 HTTP 客户端来玩,而是给 SUDS 和一个 HTTP 客户端给第三段代码,让它编排交互。
不过,通过创建基于 Twisted 的 SUDS 传输(又名 HTTP 客户端)来使事情正常工作并非不可能。 Twisted 主要使用 Deferred 的事实(又名回调)公开事件并不意味着这是它可以工作的唯一方式。通过使用第三方库,例如 greenlet ,可以提供基于协程的 API,其中对异步操作的请求涉及将执行从一个协程切换到另一个协程,并且通过切换回原始协程来传递事件。有一个项目叫corotwine可以做到这一点。可以使用它来为 SUDS 提供它想要的那种 HTTP 客户端 API;但是,这并不能保证。当上下文切换突然插入之前没有的位置时,这取决于 SUDS 不会中断。这是 SUDS 的一个非常微妙和脆弱的属性,在 future 的版本中很容易被 SUDS 开发人员改变(甚至是无意的),所以它可能不是理想的解决方案,即使你现在可以让它工作(除非你可以以 promise 在这种配置中测试他们的代码以确保其继续工作的形式获得 SUDS 维护者的合作)。
顺便说一句,Twisted Web 的 SOAP 支持仍然基于 SOAPpy 并且近两年没有修改的原因是没有明确的 SOAPpy 替代品出现。有很多竞争者(What SOAP client libraries exist for Python, and where is the documentation for them? 涵盖了其中的几个)。如果事情稳定下来,尝试更新 Twisted 的内置 SOAP 支持可能是有意义的。在那之前,我认为单独做这些集成库更有意义,这样它们可以更容易地更新,所以 Twisted 本身不会以一大堆没人想要的不同 SOAP 集成(这会比目前的情况,只有一个没人想要的 SOAP 集成模块)。
关于Python:如何使用 Twisted 作为 SUDS 的传输?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2671228/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t