Python SOAP 客户端 - 使用 SUDS 还是其他?
我现在正在研究如何实现一个客户端,这个客户端将使用一个现有的功能强大的SOAP管理API。
我查看了不同的SOAP实现,比如pysimplesoap和SUDS。第一个在解析WSDL时遇到了问题,因为递归太多,而suds运行得还不错(虽然慢),我真的很喜欢这个模块。
不过,SUDS似乎有几个问题,比如内存消耗高、WSDL解析速度慢,还有一些WSDL属性(比如choice属性)不支持。
虽然有很多人积极提交错误报告和补丁,但自2010年9月15日以来,SUDS就没有发布过新版本0.4。而且,维基和路线图看起来也有点被忽视。
对我来说,SUDS似乎不再维护了。
所以我有几个问题:
- 基于suds作为SOAP客户端来做一个较大的项目,是否合理?
- 有没有一个suds的分支,已经实现了一些在问题系统中可用的补丁?
- 有没有其他的替代方案,内存占用更低,使用起来简单,并且能够处理复杂的大WSDL文件?
[更新 2013年11月]
两年多过去了,原来的suds项目确实已经死掉了。自2010年以来没有再发布新版本。由于这个原因,很多人开始分叉suds,像Debian这样的发行版也在部署修补过的原始suds包,以解决一些问题。
我可以推荐Jurko的这个活跃维护的分支,我用得很成功。它支持Python 3,并解决了很多suds已知的问题。发布说明和错误跟踪器可以在Bitbucket上找到,这个包也可以在PyPI上获取,因此可以通过pip安装。
4 个回答
你可以在这里找到一篇有趣的最新帖子:Python有哪些SOAP客户端库,它们的文档在哪里? 很遗憾,你想要的完美SOAP库似乎还不存在(至少现在还没有)。
有一个新的、维护得很好的SOAP客户端,叫做 zeep。它支持Python 2和Python 3,并且是基于大家都很熟悉的lxml和requests库。
虽然没有官方的标准,但如果你必须使用SOAP,Suds是最好的选择。Suds在处理大型WSDL时可能会比较慢,这也是他们正在努力改进的地方。
与此同时,如果你不希望你的WSDL经常变化,有两个方法可以让你速度更快:
- 把WSDL下载到本地
- 使用缓存
下载你的WSDL
对于大型WSDL来说,问题之一是每次都需要下载WSDL,这会增加额外的时间。Suds在启动时会花时间下载并解析整个WSDL,以确保它没有变化。
如果你能把它下载到本地系统,然后通过在URL中使用file://
方案传递给Client
构造函数,那就可以了。因为Suds使用urllib2
进行HTTP传输,这样做是完全合法的。
现在,由于你在WSDL的URL中没有提供主机名,你还需要传递一个location
参数,指定SOAP应用的实际URL。
这里有个例子:
from suds.client import Client
# The service URL
soap_url = 'http://myapp.example.notreal/path/to/soap'
# The WSDL URL, we wont' use this but just illustrating for example. This
# would be the file you download to your system and save as wsdl_file
wsdl_url = 'http://myapp.example.notreal/path/to/soap?wsdl'
# The full path to the downloaded WSDL file on your local system
wsdl_file = '/path/to/myapp.wsdl'
wsdl_url = 'file://' + wsdl_file # Override original wsdl_url
client = Client(url=wsdl_url, location=soap_url)
如果你感兴趣,我在工作中使用了这种方法,并且已经把代码开源了。
缓存你的WSDL
另一个选择是使用Suds的优秀缓存功能。你必须明确创建一个缓存对象,然后通过cache
参数传递给构造函数。否则,它会默认使用一个持续时间为1天的ObjectCache
。
你也可以考虑同时使用这两种方法。