How to consume SOAP web service using Python

Consume SOAP Service

In this example I will show you 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. I will use here Python package xml.dom.minidom to create the XML request in the body. I will create HTTPS connection over the SOAP webservice.

I am not going to build any SOAP service in this example, rather I 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/3.9.1/3.11.5

Call SOAP Web Service using Postman

I 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 you will see how to call SOAP web service using Python programming language.

I 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 'Status:' + str(response.status) + ': ' + str(resp_data)

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

I have imported required packages for calling the SOAP service. As I have mentioned at the beginning that I am going to use XML and JSON as requests in the body parameter of the service so I 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 I 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.

I am using here SOAP version 1.2, hence I am using soap12 as a namespace.

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

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

Testing the Program

XML as Request Body

I will test the SOAP service which I 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

I 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:

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

That’s all about how to consume SOAP web service using Python program.

Source Code

Download

Leave a Reply

Your email address will not be published. Required fields are marked *