我想在Python中使用基于WSDL SOAP的Web服务。我查看了Dive Into Python代码,但SOAPpy模块在Python 2.5下无效。
我尝试使用部分有效的suds,但使用某些类型(suds.TypeNotFound:未找到类型:'item')。
我也查看了Client,但这似乎不支持WSDL。
我看过ZSI,但看起来很复杂。有人有任何示例代码吗?
WSDL是https://ws.pingdom.com/soap/PingdomAPI.wsdl,可以与PHP 5 SOAP客户端一起使用。
答案 0 :(得分:49)
我建议您查看SUDS
“Suds是一个用于使用Web服务的轻量级SOAP python客户端。”
答案 1 :(得分:19)
我最近偶然发现了同样的问题。以下是我的解决方案的概要:
所需的基本组成代码块
以下是客户端应用程序所需的基本代码块
您需要哪些模块?
许多人建议使用像urllib2这样的Python模块;但是,没有一个模块可以工作 - 至少对于这个特定的项目而言。
所以,这是您需要获得的模块列表。 首先,您需要从以下链接下载并安装最新版本的suds:
pypi.python.org/pypi/suds-jurko/0.4.1.jurko.2
此外,您需要分别从以下链接下载和安装请求和suds_requests模块(免责声明:我是新来的,因此我现在不能发布多个链接。)
pypi.python.org/pypi/requests
pypi.python.org/pypi/suds_requests/0.1
成功下载并安装这些模块后,您就可以开始使用了。
代码
按照前面列出的步骤,代码如下所示: 进口:
import logging
from suds.client import Client
from suds.wsse import *
from datetime import timedelta,date,datetime,tzinfo
import requests
from requests.auth import HTTPBasicAuth
import suds_requests
会话请求和身份验证:
username=input('Username:')
password=input('password:')
session = requests.session()
session.auth=(username, password)
创建客户端:
client = Client(WSDL_URL, faults=False, cachingpolicy=1, location=WSDL_URL, transport=suds_requests.RequestsTransport(session))
添加WS-Security标头:
...
addSecurityHeader(client,username,password)
....
def addSecurityHeader(client,username,password):
security=Security()
userNameToken=UsernameToken(username,password)
timeStampToken=Timestamp(validity=600)
security.tokens.append(userNameToken)
security.tokens.append(timeStampToken)
client.set_options(wsse=security)
请注意,此方法会创建图1中所示的安全标头。因此,您的实施可能会有所不同,具体取决于您正在使用的服务所有者提供的正确的安全标头格式。
采用相关方法(或操作):
result=client.service.methodName(Inputs)
<强>登录强>:
这种实现中的最佳实践之一就是记录通信的执行方式。如果出现问题,可以轻松调试。以下代码执行基本日志记录。但是,除了代码中描述的内容之外,您还可以记录通信的许多方面。
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)
logging.getLogger('suds.transport').setLevel(logging.DEBUG)
<强>结果:强>
这是我案例中的结果。请注意,服务器返回HTTP 200.这是HTTP请求 - 响应的标准成功代码。
(200, (collectionNodeLmp){
timestamp = 2014-12-03 00:00:00-05:00
nodeLmp[] =
(nodeLmp){
pnodeId = 35010357
name = "YADKIN"
mccValue = -0.19
mlcValue = -0.13
price = 36.46
type = "500 KV"
timestamp = 2014-12-03 01:00:00-05:00
errorCodeId = 0
},
(nodeLmp){
pnodeId = 33138769
name = "ZION 1"
mccValue = -0.18
mlcValue = -1.86
price = 34.75
type = "Aggregate"
timestamp = 2014-12-03 01:00:00-05:00
errorCodeId = 0
},
})
答案 2 :(得分:16)
有一个相对较新的图书馆非常有前景,虽然记录很少,看起来很干净和pythonic:python zeep。
另请参阅this answer示例。
答案 3 :(得分:8)
现在(截至2008年),所有可用于Python的SOAP库都很糟糕。我建议尽可能避免使用SOAP。我们最后一次被迫使用Python的SOAP Web服务时,我们在C#中编写了一个包装器,它在一侧处理SOAP并将COM传递给另一方。
答案 4 :(得分:5)
我会定期搜索一个令人满意的答案,但到目前为止还没有运气。我使用soapUI +请求+手工劳动。
我最后一次需要放弃并使用Java来做这件事,并且在上次想要这样做时放弃了几次,但它不是必不可少的。
去年使用Project Place的RESTful API成功使用了请求库后,我想到也许我可以用类似的方式手动滚动我想要发送的SOAP请求。
事实证明这并不太难,但 耗时且容易出错,尤其是如果字段命名不一致(我现在正在处理的那个有'jobId',JobId'和'JobID'。我使用soapUI加载WSDL,以便更容易提取端点等,并执行一些手动测试。到目前为止,我很幸运没有受到我正在使用的任何WSDL的更改的影响。< / p>
答案 5 :(得分:4)
Zeep是一个适合Python的SOAP库,可以满足您的要求:http://docs.python-zeep.org
答案 6 :(得分:2)
不正确SOAPpy不能与Python 2.5一起使用 - 虽然它非常简单,但实际上非常基本,所以它很有用。如果您想与任何更复杂的网络服务交谈,ZSI是您唯一的朋友。
我发现真正有用的演示是在http://www.ebi.ac.uk/Tools/webservices/tutorials/python - 这真的帮助我理解了ZSI的工作原理。
答案 7 :(得分:1)
如果您自己推销,我强烈建议您查看http://effbot.org/zone/element-soap.htm。
答案 8 :(得分:1)
SOAPpy现已过时,AFAIK被ZSL取代。这是一个没有实际意义的问题,因为在Python 2.5或Python 2.6上我无法使用任何一个工作,更不用说编译了
答案 9 :(得分:1)
#!/usr/bin/python
# -*- coding: utf-8 -*-
# consume_wsdl_soap_ws_pss.py
import logging.config
from pysimplesoap.client import SoapClient
logging.config.dictConfig({
'version': 1,
'formatters': {
'verbose': {
'format': '%(name)s: %(message)s'
}
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'verbose',
},
},
'loggers': {
'pysimplesoap.helpers': {
'level': 'DEBUG',
'propagate': True,
'handlers': ['console'],
},
}
})
WSDL_URL = 'http://www.webservicex.net/stockquote.asmx?WSDL'
client = SoapClient(wsdl=WSDL_URL, ns="web", trace=True)
client['AuthHeaderElement'] = {'username': 'someone', 'password': 'nottelling'}
#Discover operations
list_of_services = [service for service in client.services]
print(list_of_services)
#Discover params
method = client.services['StockQuote']
response = client.GetQuote(symbol='GOOG')
print('GetQuote: {}'.format(response['GetQuoteResult']))