How to consume SOAP web service using Python

Introduction

In this example we will see how to consume SOAP web service using Python. In this example mainly I will show you how to call POST request with XML or JSON as a request in the body. We will use here Python package xml.dom.minidom to create the XML request in the body. We will create HTTPS connection over the SOAP webservice.

We are not going to build any SOAP service in this example, rather we will use existing SOAP service from w3schools where there is already ready made SOAP service about temperature converter which can be used for testing purpose.

Related Posts:

Prerequisites

Python 3.8.1

Call SOAP Web Service using Postman

We will first test the SOAP web service using Postman tool. You can also use SOAP UI for SOAP service testing but I think Postman is light-weight tool.

Request Details

Here are the request details of the temperature converter SOAP service.

HTTPS Method: POST

Service URL: https://www.w3schools.com/xml/tempconvert.asmx

Content Type: application/soap+xml (this should go in the Headers)

Request Body:

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <CelsiusToFahrenheit xmlns="https://www.w3schools.com/xml/">
      <Celsius>36</Celsius>
    </CelsiusToFahrenheit>
  </soap12:Body>
</soap12:Envelope>

Response Details

Clicking on the Send button will give you the following response:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <CelsiusToFahrenheitResponse xmlns="https://www.w3schools.com/xml/">
            <CelsiusToFahrenheitResult>96.8</CelsiusToFahrenheitResult>
        </CelsiusToFahrenheitResponse>
    </soap:Body>
</soap:Envelope>

Call SOAP Service using Python

Now we will see how to call SOAP web service using Python programming language.

We will write the Python code in Object Oriented way.

import http.client
import urllib.parse
import xml.dom.minidom

class soap_consumer:

	def __init__(self, msg, json=False):
		self.msg = msg
		self.json = json
	
	def envelope(self):
		if self.json:
			return self.msg
		else:
			doc = xml.dom.minidom.Document()
			env = doc.createElement('soap12:Envelope')
			env.setAttribute('xmlns:soap12', 'http://www.w3.org/2003/05/soap-envelope')
			env.setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance')
			env.setAttribute('xmlns:xsd', 'http://www.w3.org/2001/XMLSchema')
			
			#print(self.msg)
			
			#XML input request data
			rawdom = xml.dom.minidom.parseString(self.msg)		
			messagenode = rawdom.firstChild
			
			#Header
			header = doc.createElement('soap12:Header')
			env.appendChild(header)
			
			#Body
			body = doc.createElement('soap12:Body')
			body.appendChild(messagenode)
			
			env.appendChild(body)
			doc.appendChild(env)
			
			#print(doc.toxml('utf-8'))
			
			return doc.toxml('utf-8')
	
	def send_request(self, url, path, content_type, accept, https=True):
		data = self.envelope()
		
		#print(data)
		#print(len(data))
		
		headers = {"Content-type" : content_type, "Accept": accept, "Content-length": len(data)}
		conn = ''
		
		if https:
			conn = http.client.HTTPSConnection(url, 443)
		else:
			conn = http.client.HTTPConnection(url, 80)

		#print(conn)
		conn.request("POST", path, data, headers)
		
		response = conn.getresponse()
		resp_data = response.read()
		
		#print(resp_data)
		
		if response.status == 200:
			conn.close()
			return resp_data
		else:
			return 'Failed:' + str(response.status) + str(resp_data)

Now we will see what we have written into the above Python code.

We have imported required packages for calling the SOAP service. As we have mentioned at the beginning that we are going to use XML and JSON as requests in the body parameter of the service so we have declared json=False in the constructor. The msg variable will hold the input request passed as XML or JSON.

You can always modify the code as per your requirements and idea here is to show you how to call SOAP service using Python programming.

Next we define a function which will build the envelop if it is XML otherwise it will just return the JSON string.

The envelop which I have created here will work just for the specified service which was earlier tested using Postman tool. You have to modify the code if you have different structure.

We are using here SOAP version 1.2, hence we are using soap12 as a namespace.

Next we define send_request() function which takes a number of parameters for SOAP service.

We check whether we need to connect to HTTP or HTTPS protocol and accordingly we decide upon the last parameter of the function send_request().

Testing the Program

XML as Request Body

We will test the SOAP service which we have tested using Postman tool in the above.

swsc = soap_consumer('<CelsiusToFahrenheit xmlns="https://www.w3schools.com/xml/"><Celsius>36</Celsius></CelsiusToFahrenheit>')
resp = swsc.send_request('www.w3schools.com', '/xml/tempconvert.asmx', 'application/soap+xml; charset=utf-8', 'text/xml')
print(resp)

Response:

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><CelsiusToFahrenheitResponse xmlns="https://www.w3schools.com/xml/"><CelsiusToFahrenheitResult>96.8</CelsiusToFahrenheitResult></CelsiusToFahrenheitResponse></soap:Body></soap:Envelope>

JSON as Request Body

We will test different SOAP service that needs JSON as a request body.

params = urllib.parse.urlencode({'@number': 12524, '@type': 'issue', '@action': 'show'})
swsc = soap_consumer(params, True)
resp = swsc.send_request('bugs.python.org', '', 'application/x-www-form-urlencoded; charset=utf-8', 'text/plain')
print(resp)

Response:

Redirecting to <a href="https://bugs.python.org/issue12524">https://bugs.python.org/issue12524</a>

That’s all.

Download

Thanks for reading.

Leave a Comment