Part 4: SOAP Client Development with zeep

Working with zeep

zeep is the most practical Python library for consuming SOAP services. It handles WSDL parsing, XML serialisation, type mapping, and response deserialisation automatically. I have used zeep to integrate with banking payment gateways, government identity verification APIs, and legacy ERP inventory feeds β€” all of which required SOAP.

This part covers everything needed to build a robust zeep client: loading WSDLs, calling operations, mapping complex responses, managing persistent sessions, caching WSDLs for production, and debugging when things go wrong.

Installing zeep

pip install zeep[xmlsec]   # xmlsec adds XML signature support for WS-Security (Part 5)

For projects that do not need WS-Security:

pip install zeep

Basic Client Setup

The minimal zeep client loads a WSDL and calls an operation:

# basic_client.py
from zeep import Client

client = Client("http://www.dneonline.com/calculator.asmx?WSDL")
result = client.service.Add(intA=15, intB=27)
print(result)   # 42

zeep reads the WSDL, understands the Add operation takes two integers, and handles all the XML construction and parsing.

For services where the endpoint URL is different from where the WSDL lives (common with staging/production environments), override the endpoint:

create_service is the correct way to target a different endpoint than the WSDL specifies β€” I use this pattern in almost every real-world integration where there is a test environment URL separate from the WSDL URL.

Inspecting Available Operations

Before writing client code, I always check what operations are available:

This prints a human-readable summary of services, ports, and operations with their input/output types. Extremely useful when working with undocumented or poorly documented services.

Calling Operations and Handling Responses

Simple Types

Complex Nested Types

When an operation takes a complex type as input, pass it as a dictionary or construct it with the factory:

I prefer Method 1 (plain dict) for simple cases and Method 2 (factory) when I need to reuse the type object, validate its shape, or pass it to multiple operations.

List Responses

When a response contains an array type, zeep returns it as a Python list:

Serialising Responses to Dictionaries

zeep's native objects can be converted to plain Python dicts using serialize_object:

Session Management and Persistent Connections

SOAP services over HTTPS benefit from HTTP keep-alive and session cookie support. Use requests.Session with zeep's Transport:

For production clients, always set explicit timeouts. SOAP services β€” especially older enterprise systems β€” can hang indefinitely on network issues. A client without timeouts will block threads and exhaust thread pools.

Caching WSDLs for Production

Loading a WSDL on every client instantiation means an HTTP request to the service. For high-volume applications or services with slow WSDL endpoints, cache the WSDL locally:

With SqliteCache, the first request downloads and caches the WSDL. Subsequent instantiations resolve from the cache until the timeout expires.

For long-running services or when you know the WSDL will never change, download it once and load from disk:

Debugging: Logging Raw SOAP Traffic

When the client behaves unexpectedly, the first thing I do is enable transport logging to see the raw XML on the wire.

The log output shows:

  • The full HTTP request with headers and body

  • The raw SOAP response XML

  • Any XML parsing or binding steps

For production, log only errors:

To capture the raw XML programmatically without printing to logs, use a custom transport:

Handling Optional Fields and None Values

SOAP types have minOccurs="0" fields that behave differently from what Python developers expect. zeep returns None for absent optional elements:

When building input for operations with many optional fields, only include the ones you need in the dict:

Building a Production-Ready Client Class

For real projects, I wrap the zeep client in a class that manages its lifecycle, adds retry logic, and provides typed methods:

Usage:

What's Next

You can now build robust zeep clients that:

  • Load and cache WSDLs

  • Call operations with simple and complex types

  • Debug raw SOAP traffic

  • Manage persistent sessions with timeouts

  • Retry on transient network failures

In Part 5, we add security to SOAP messages using WS-Security β€” covering UsernameToken, message timestamps, and digital signatures with X.509 certificates.

Last updated