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

时间:2008-09-22 14:58:54

标签: python web-services soap

我想在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客户端一起使用。

10 个答案:

答案 0 :(得分:49)

我建议您查看SUDS

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

答案 1 :(得分:19)

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

所需的基本组成代码块

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

  1. 会话请求部分:请求与提供商的会话
  2. 会话身份验证部分:向提供商提供凭据
  3. 客户端部分:创建客户端
  4. 安全标题部分:将WS-Security标头添加到客户端
  5. 消费部分:根据需要消耗可用的操作(或方法)
  6. 您需要哪些模块?

    许多人建议使用像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']))