如何在Python中使用WSDL(SOAP)Web服务?


124

我想在Python中使用基于WSDL SOAP的Web服务。我看过Dive Into Python代码,但是SOAPpy模块在Python 2.5下不起作用。

我已经尝试使用肥皂水(:类型未找到:“项目” suds.TypeNotFound),这部分工作,但打破了某些类型。

我也查看了Client,但这似乎不支持WSDL。

我看过ZSI,但它看起来非常复杂。有人有任何示例代码吗?

WSDL是https://ws.pingdom.com/soap/PingdomAPI.wsdl,可与PHP 5 SOAP客户端配合使用。


3
您会考虑更改您接受的答案吗?当前接受的答案是-1,还有另一个答案是+19。我知道这是从2008年开始的;我只是在建议。
Mark E. Haase 2012年

SUDS无法正常工作,因为它无法正确解析WSDL,但否则将是一个不错的选择。因此,我将答案更改为Dive Into Python中的教程,其中有一些替代方法。作为附带说明,Pingdom现在具有一个REST API pingdom.com/services/api-documentation-rest,其客户端库位于blog.pingdom.com/2011/04/11/pingdom-rest-api-wrappers
davidmytton

Answers:


49

我建议您看看SUDS

“ Suds是用于使用Web服务的轻量级SOAP python客户端。”


第二。对我而言,Suds立刻就有意义,不需要生成类,它可以实时加载WSDL并创建一个可以立即从中使用的对象。
EnigmaCurry 2011年

19
当使用递归导入打开WSDL时,Suds有一个无限递归问题。Suds认为这是一个阻止错误,该问题创建于3年前,但是尚未修复。 fedorahosted.org/suds/ticket/239 这让我想知道Suds是否适合2012年使用?
Buttons840

2
泡沫似乎已经死了。SUDS万岁 -这似乎是活跃的Fork。
nerdoc

3
这是最重要的答案,但是如果有人在寻找今天可以使用的答案,则也可以考虑Zeep,这也是较新的答案所建议的。
Tobias Feil

25

有一个相对较新的库,它很有前途,尽管文档仍然很少,但看起来很干净并且是pythonic的python zeep

另请参见此答案的示例。


2
为此+1。我今天尝试了zeep,它非常易于使用。能够使用3行代码使用和调用Soap 1.1 / 1.2服务。
Jagu

20

我最近偶然发现了同样的问题。这是我的解决方案的摘要:

所需的基本组成代码块

以下是客户端应用程序所需的基本代码块

  1. 会话请求部分:请求与提供者进行会话
  2. 会话认证部分:向提供者提供凭据
  3. 客户端部分:创建客户端
  4. 安全标题部分:将WS-Security标头添加到客户端
  5. 消耗部分:根据需要消耗可用的操作(或方法)

您需要什么模块?

许多建议使用Python模块,例如urllib2;但是,这些模块都不起作用-至少对于该特定项目不起作用。

因此,这是您需要获取的模块列表。首先,您需要从以下链接下载并安装最新版本的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)

结果:

这是我的情况的结果。请注意,服务器返回了HTTP200。这是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
      },
 })

1
也许值得一说,suds_request安装会失败,因此,如果您使用的是suds-jurko前叉,则可以安装suds_request适用于Jurko版本的肥皂水的产品:pip install git+https://github.com/chrcoe/suds_requests.git@feature/python3_suds_jurko
errata

7

现在(截止到2008年),所有可用于Python的SOAP库都非常烂。我建议尽可能避免使用SOAP。上次我们被迫使用Python中的SOAP Web服务时,我们用C#编写了一个包装器,该包装器一方面处理SOAP,另一方面则使COM退出。


15
这听起来像是使用基于xml和http的简单协议的极其复杂的方法。
ddaa 2012年

1
到了2008年,这才是满足我们需求的最小方法。我似乎还记得那个特定的Web服务对于所有python库都出错了的情况非常挑剔。
马修·斯科腾

1
2019年,python zeep,suds仍然容易出现许多解析不兼容问题。维护不佳的wsdl文件会使这些模块抛出异常,例如不间断的鞭炮。
讨论


6

我定期寻找一个令人满意的答案,但是到目前为止还没有运气。我使用soapUI +请求+体力劳动。

我上次要这样做时放弃并使用了Java ,而上次我这样做时仅放弃了几次,但这并不是必需的。

去年在Project Place的RESTful API中成功使用了请求库之后,我想到也许我可以以类似的方式手动滚动要发送的SOAP请求。

事实证明,这并不是很困难,但是这耗时且容易出错,尤其是如果字段名称不一致(我当前正在使用的字段具有“ jobId”,“ JobId”和“ JobID”。我使用soapUI加载) WSDL,以便更轻松地提取端点等并执行一些手动测试。到目前为止,我很幸运没有受到我正在使用的任何WSDL更改的影响。


3

并非如此,SOAPpy不适用于Python 2.5-它可以工作,尽管它非常简单,而且确实非常基础。如果您想与任何更复杂的Web服务进行对话,则ZSI是您唯一的朋友。

我发现的真正有用的演示位于http://www.ebi.ac.uk/Tools/webservices/tutorials/python-这确实帮助我了解了ZSI的工作原理。


1
python setup.py install提供了最新版本的错误。最新的开发人员副本可能有效,但这是一件很痛苦的事情。
davidmytton


1

SOAPpy现在已过时,已经被ZSL取代了AFAIK。这是有争议的,因为在Python 2.5或Python 2.6上我都无法工作,更不用说编译了。


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']))


示例输出:... DEBUG:pysimplesoap.helpers:complexContent / simpleType / element string = string [u'StockQuote'] GetQuote:<StockQuotes> <Stock> <Symbol> GOOG </ Symbol> <Last> 816.13 </ Last> <Da​​te> 3/23/2017 </ Date> <Time> 11:41 am </ Time> <Change> -13.46 </ Change> <Open> 820.01 </ Open> <High> 822.57 </ High> <Low> 812.26 </ Low> <Volume> 1973140 </ Volume> <MktCap> 564.29B </ MktCap> <PreviousClose> 829.59 </ PreviousClose> <PercentageChange> -1.62%</ PercentageChange> <AnnRange> 663.28-853.50 </ AnnRange> <Earns> 27.88 </ Earns> <PE> 29.28 </ PE> <Name> Alphabet Inc。</ Name> </ Stock> </ StockQuotes>
往下流

在pysimplesoap / client.py:757中的Python3上失败-'dict'对象没有属性'iteritems'–
ierdna

显然,PIP随附的版本已损坏。必须从GIT手动安装-它可以解决问题
ierdna

好点:请查看此链接:stackoverflow.com/questions/13998492/iteritems-in-python “ dict.iteritems已删除,因为dict.items现在可以执行dict.iteritems在python 2中所做的事情...”
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.