首页 文章

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

提问于
浏览
115

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

11 回答

  • 14

    我知道这是一个老线程,但它出现在Google的结果顶部,所以我想分享一个关于Python和SOAP的更新的讨论 .

    见:http://www.diveintopython.net/soap_web_services/index.html

  • 2

    我建议你看看SUDS

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

  • 1

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

    Basic constituent code blocks needed

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

    • 会话请求部分:请求与提供者的会话

    • 会话身份验证部分:向提供者提供凭据

    • 客户端部分:创建客户端

    • 安全 Headers 部分:将WS-Security标头添加到客户端

    • 消耗部分:根据需要消耗可用的操作(或方法)

    What modules do you need?

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

    成功下载并安装这些模块后,您就可以开始使用了 .

    The code

    按照前面概述的步骤,代码如下所示: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
    

    会话请求和身份验证:

    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

    这种实现中的最佳实践之一就是记录通信的执行方式 . 如果出现问题,可以轻松调试 . 以下代码执行基本日志记录 . 但是,除了代码中描述的方面之外,您还可以记录通信的许多方面 .

    logging.basicConfig(level=logging.INFO) 
    logging.getLogger('suds.client').setLevel(logging.DEBUG) 
    logging.getLogger('suds.transport').setLevel(logging.DEBUG)
    

    Result:

    这是我的结果 . 请注意,服务器返回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
          },
     })
    
  • 42

    有一个相对较新的图书馆非常有前途,虽然仍然记录不完整,似乎非常干净和pythonic:python zeep .

    有关示例,另请参见this answer .

  • 7

    现在(截至2008年),所有可用于Python的SOAP库都很糟糕 . 我建议尽可能避免使用SOAP . 我们最后一次被迫使用Python的SOAP Web服务时,我们在C#中编写了一个包装器,它在一侧处理SOAP并将COM传递给另一方 .

  • 1

    我会定期寻找一个满意的答案,但到目前为止还没有运气 . 我使用soapUI请求手工劳动 .

    我最后一次需要这样做时放弃并使用了Java,并且在我上次想要这样做的时候放弃了几次,但这并不重要 .

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

    事实证明这并不太难,但它很耗时且容易出错,特别是如果字段名称不一致(我使用soapUI来加载WSDL以便更容易提取 endpoints 等等)一些手动测试 . 到目前为止我've been lucky not to have been affected by changes to any WSDL that I'米使用 .

  • 1

    Zeep是一个适合Python的SOAP库,可以满足您的需求:http://docs.python-zeep.org

  • 3

    这不是真的,SOAPpy不能与Python 2.5一起使用 - 虽然它非常简单,但实际上非常基本 . 如果您想与任何更复杂的网络服务交谈,ZSI是您唯一的朋友 .

    我找到的真正有用的演示是在http://www.ebi.ac.uk/Tools/webservices/tutorials/python - 这真的帮助我了解ZSI的工作原理 .

  • 49

    如果你强烈推荐're rolling your own I' .

  • 5

    SOAPpy现已过时,AFAIK由ZSL取代 . 这是一个有争议的问题,因为我不能让任何一个工作,更不用说编译,在Python 2.5或Python 2.6上

  • 19
    #!/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']))
    

相关问题