Tutorial :How can I consume a WSDL (SOAP) web service in Python?



Question:

I want to use a WSDL SOAP based web service in Python. I have looked at the Dive Into Python code but the SOAPpy module does not work under Python 2.5.

I have tried using suds which works partly, but breaks with certain types (suds.TypeNotFound: Type not found: 'item').

I have also looked at Client but this does not appear to support WSDL.

And I have looked at ZSI but it looks very complex. Does anyone have any sample code for it?

The WSDL is https://ws.pingdom.com/soap/PingdomAPI.wsdl and works fine with the PHP 5 SOAP client.


Solution:1

I know this is an old thread but it was showing up at the top of Google's results so I wanted to share a more current discussion on Python and SOAP.

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


Solution:2

I would recommend that you have a look at SUDS

"Suds is a lightweight SOAP python client for consuming Web Services."


Solution:3

I recently stumbled up on the same problem. Here is the synopsis of my solution:

Basic constituent code blocks needed

The following are the required basic code blocks of your client application

  1. Session request section: request a session with the provider
  2. Session authentication section: provide credentials to the provider
  3. Client section: create the Client
  4. Security Header section: add the WS-Security Header to the Client
  5. Consumption section: consume available operations (or methods) as needed

What modules do you need?

Many suggested to use Python modules such as urllib2 ; however, none of the modules work-at least for this particular project.

So, here is the list of the modules you need to get. First of all, you need to download and install the latest version of suds from the following link:

pypi.python.org/pypi/suds-jurko/0.4.1.jurko.2

Additionally, you need to download and install requests and suds_requests modules from the following links respectively ( disclaimer: I am new to post in here, so I can't post more than one link for now).

pypi.python.org/pypi/requests

pypi.python.org/pypi/suds_requests/0.1

Once you successfully download and install these modules, you are good to go.

The code

Following the steps outlined earlier, the code looks like the following: 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  

Session request and authentication:

username=input('Username:')  password=input('password:')  session = requests.session()  session.auth=(username, password)  

Create the Client:

client = Client(WSDL_URL, faults=False, cachingpolicy=1, location=WSDL_URL, transport=suds_requests.RequestsTransport(session))  

Add WS-Security Header:

...  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)  

Please note that this method creates the security header depicted in Fig.1. So, your implementation may vary depending on the correct security header format provided by the owner of the service you are consuming.

Consume the relevant method (or operation) :

result=client.service.methodName(Inputs)  

Logging:

One of the best practices in such implementations as this one is logging to see how the communication is executed. In case there is some issue, it makes debugging easy. The following code does basic logging. However, you can log many aspects of the communication in addition to the ones depicted in the code.

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

Result:

Here is the result in my case. Note that the server returned HTTP 200. This is the standard success code for HTTP request-response.

(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        },   })  


Solution:4

There is a relatively new library which is very promising and albeit still poorly documented, seems very clean and pythonic: python zeep.

See also this answer for an example.


Solution:5

Right now (as of 2008), all the SOAP libraries available for Python suck. I recommend avoiding SOAP if possible. The last time we where forced to use a SOAP web service from Python, we wrote a wrapper in C# that handled the SOAP on one side and spoke COM out the other.


Solution:6

I periodically search for a satisfactory answer to this, but no luck so far. I use soapUI + requests + manual labour.

I gave up and used Java the last time I needed to do this, and simply gave up a few times the last time I wanted to do this, but it wasn't essential.

Having successfully used the requests library last year with Project Place's RESTful API, it occurred to me that maybe I could just hand-roll the SOAP requests I want to send in a similar way.

Turns out that's not too difficult, but it is time consuming and prone to error, especially if fields are inconsistently named (the one I'm currently working on today has 'jobId', JobId' and 'JobID'. I use soapUI to load the WSDL to make it easier to extract endpoints etc and perform some manual testing. So far I've been lucky not to have been affected by changes to any WSDL that I'm using.


Solution:7

It's not true SOAPpy does not work with Python 2.5 - it works, although it's very simple and really, really basic. If you want to talk to any more complicated webservice, ZSI is your only friend.

The really useful demo I found is at http://www.ebi.ac.uk/Tools/webservices/tutorials/python - this really helped me to understand how ZSI works.


Solution:8

Zeep is a decent SOAP library for Python that matches what you're asking for: http://docs.python-zeep.org


Solution:9

If you're rolling your own I'd highly recommend looking at http://effbot.org/zone/element-soap.htm.


Solution:10

SOAPpy is now obsolete, AFAIK, replaced by ZSL. It's a moot point, because I can't get either one to work, much less compile, on either Python 2.5 or Python 2.6


Solution:11

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

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »