Using Zeep to make SOAP requests in Python

While most APIs are REST these days, there are still some SOAP ones out there — typically enterprise software or if you need the benefits of WS-security or the like. What brought me to SOAP was integrating with an enterprise payment gateway that had developed their own clients in several languages, but not Python, so I was on the hunt for my own. There are others, the short version of why I went with Zeep is because it was purported to be the most “modern” — we can argue about whether this was a good decision or rationale some other time. This is a pretty basic overview, but should enable you to make your first requests and clear up some hurdles I faced when some things were less clear than I would have liked in the docs.

Passing Parameters/Generating XML

One of the nice things about using Zeep is that you don’t actually need to write XML, which can be finicky. Create a dictionary with the relevant data, and it will create XML for you, based on an XML schema that you provide it (more on that later). For example, the following dictionary:

Results in the following XML:

It’s worth noting that parameters are passed into Zeep the same way fields are. The schema includes both attributes and fields, so they are applied correctly. Another thing to note is that boolean values should be passed in as lowercase strings, not as Python boolean values — Zeep doesn’t know to translate from an actual boolean.

Update: heard from a reader looking to include both an attribute and a field in the same element — i.e if I had wanted the tax_service element above to read <taxService run="true">WA, CA</taxService> instead. That can be accomplished by doing something like

Find it mentioned here in the docs.

The Zeep Client

Zeep gets access to the XML schema mentioned above via the WSDL that is passed into the Zeep client when it is initialized. A WSDL is a Web Service Description Language — it describes what an endpoint can do; what parameters and operations it accepts, and also links to an XML schema. The WSDL typically contains something like this:

Or:

In both cases, <schema> will point to another location on the web where a detailed schema can be found.

The client can be initialized like so:

This gives the client both the WSDL and your security credentials via WS-Security. It will generate an appropriate XML envelope.

To use the client, you’ll need to know which methods are available to it. This is not native to Zeep, which makes it a bit harder to parse if your habit for figuring out how things work, like mine, is going into the source code itself — you won’t find the method names there. You’ll need to see what operations are available to the API you’re using. The WSDL that I created my client with includes this line:

<wsdl:operation name="runTransaction">

This means I have access to runTransaction as a method on my client service, which I can use like so:

client.service.runTransaction(**request_data)

The Response

Zeep handles XML parsing the response for you too. The response object you’ll get back can be accessed just like a dictionary, but isn’t a dictionary. This means you can do things like response['key'], but you can’t do response.get('key', None). The good news is that if a given key doesn’t exist, it won’t throw a KeyError, but will just return None.

Senior Software Engineer | www.adriennedomingus.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store