我如何在Python中使用WSDL(SOAP)Web服务?
我想在Python中使用基于WSDL SOAP的Web服务。 我已经看了一下Dive Into Python代码,但是SOAPpy模块在Python 2.5下不工作。
我尝试过使用一部分工作的泡沫 ,但是破坏了某些types(suds.TypeNotFound:Type not found:'item')。
我也看过客户端,但这似乎并不支持WSDL。
我曾看过ZSI,但看起来非常复杂。 有没有人有任何示例代码?
WSDL是https://ws.pingdom.com/soap/PingdomAPI.wsdl,并且与PHP 5 SOAP客户端一起工作良好。
我知道这是一个古老的线程,但它显示在Google的结果的顶部,所以我想分享一个关于Python和SOAP的更新的讨论。
请参阅: http : //www.diveintopython.net/soap_web_services/index.html
我build议你看看SUDS
“Suds是一个用于使用Web服务的轻量级SOAP Python客户端。”
我最近偶然发现了同样的问题。 这里是我的解决scheme的简介:
基本组成代码块需要
以下是您的客户端应用程序所需的基本代码块
- 会话请求部分:向提供者请求会话
- 会话authentication部分:向提供者提供凭证
- 客户端部分:创build客户端
- 安全标题部分:将WS-Security标题添加到客户端
- 消费部分:根据需要使用可用的操作(或方法)
你需要什么模块?
许多人build议使用Python模块,如urllib2; 然而,这些模块都没有工作 – 至less对于这个特定的项目来说。
所以,这里是你需要得到的模块列表。 首先,您需要从以下链接下载并安装最新版本的泡沫:
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
一旦你成功的下载并安装了这些模块,你就可以走了。
代码
按照前面概述的步骤,代码如下所示:Imports:
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
会话请求和authentication:
username=input('Username:') password=input('password:') session = requests.session() session.auth=(username, password)
创build客户端:
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)
请注意,这个方法创build了如图1所示的安全头。 所以,您的实现可能会有所不同,具体取决于正在使用的服务的所有者提供的正确的安全头格式。
消耗相关的方法(或操作):
result=client.service.methodName(Inputs)
日志logging :
在这样的实现中的最佳实践之一就是logging如何执行通信。 如果出现问题,可以使debugging变得简单。 以下代码执行基本日志logging。 但是,除了代码中描述的内容之外,还可以logging通信的许多方面。
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 }, })
现在(截至2008年),所有可用于Python的SOAP库吸引。 如果可能,我build议避免使用SOAP。 上一次我们不得不使用Python的SOAP Web服务时,我们在C#中编写了一个包装器,它在一边处理SOAP,另一边讲COM。
有一个相对较新的图书馆是非常有前途的,尽pipe仍然很less文件logging,似乎很干净, pythonic : python zeep 。
另请参阅此答案的示例。
我定期寻找一个满意的答案,但迄今为止没有运气。 我使用soapUI +请求+手动劳动。
我放弃了,最后一次使用Java,我最后一次需要这样做,只是放弃了最后一次,我想这样做,但它不是必要的。
在去年使用Project Place的RESTful API成功使用了请求库之后,我想到了,也许我可以用类似的方式手动发送我想要发送的SOAP请求。
结果并不难,但是这样做很耗时,而且容易出错,特别是如果字段名称不一致的话(我目前正在使用的那个名字是'jobId',JobId'和'JobID'),我用soapUI加载WSDL使得更容易提取端点等,并执行一些手动testing。到目前为止,我很幸运,没有受到我使用的任何WSDL更改的影响。
这不是真的SOAPpy不适用于Python 2.5 – 它工作,虽然它非常简单,真的很基础。 如果你想谈谈更复杂的networking服务,ZSI是你唯一的朋友。
我发现真正有用的演示在http://www.ebi.ac.uk/Tools/webservices/tutorials/python-这真的帮助我了解ZSI如何工作。;
Zeep是一个很好的Python的SOAP库,可以匹配你所要求的: http : //docs.python-zeep.org
如果你自己动手,我强烈build议看看http://effbot.org/zone/element-soap.htm 。
SOAPpy现在已经过时了,AFAIK被ZSL所取代。 这是一个有争议的问题,因为我不能让任何一个人在Python 2.5或Python 2.6上工作,更不用说编译
#!/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']))