Python SOAP Client - use SUDS or something else?
Asked Answered
P

4

64

I am currently looking into implementing a client which will use an existing extensive SOAP management API.

I looked into different SOAP implementations like pysimplesoap and SUDS. While the first had problems parsing the WSDL because of too much recursions, suds worked fine (but slow) and I really like module.

However, there seem to be several issues with SUDS like the high memory consumption, the WSDL parsing speed and missing support for some WSDL attributes (eg. choice attribute).
While there are a lot of people actively committing bug reports and patches, there was no release of SUDS since 0.4 on 2010-09-15. Also, the wiki and roadmap look a bit neglected.

For me it looks like SUDS is no longer maintained.

So here my questions:

  1. Does it make sense to base a larger project on suds as soap client?
  2. Is there a suds fork that already implements some of the patches available in the ticketing system?
  3. What alternatives are available, that have a lower memory footprint and are easy to use and can handle complex large WSDL files

[Update November 2013]

More than two years have passed and it turns out the original suds project is really dead. There have been no further releases since 2010. Due to this fact a lot of people started forking suds and and distributions like Debian are deploying patched versions of the original suds package to fix some of the issues.

I can recommend Jurko's actively maintained fork which I used successfully. It supports python 3 and addresses a lot of suds' known problems. Release notes and bug tracker are available on Bitbucket the package is also available on PyPI so it can be installed using pip.

Persimmon answered 12/10, 2011 at 11:49 Comment(3)
The wiki changes where mostly about the 0.4 version which has been released in 2010 (build numbers and stuff like that). Over the last 365 days there where about 11 commits by a single contributor, most of them very minor updates (1-2 loc). None of the commits resulted in a new releasePersimmon
We can confirm circus's above remark: no new release from original suds since 2010. However niekas noticed a suds fork is maintained: suds-jurko ;-)Viveca
As of March 2017, Jurko confirmed that he is no longer maintaining it. A fork of Jurko's fork is now being maintained and published to PyPI: pip install suds-communityCuthburt
F
50

While there isn't a certified standard, if you must use SOAP, Suds is your best choice. Suds can be slow on large WSDLs, and that is something they are working on.

In the meantime, if you don't expect your WSDL to change often, you have two options that can buy you a lot of speed:

  1. Downloading your WSDL to localhost
  2. Using caching

Downloading your WSDL

With large WSDLs part of the problem is that first you must download the WSDL every time, which can add overhead. Suds will take the time to download and parse the entire WSDL on startup to make sure that it hasn't changed.

If you can download it to the local system and then pass it to the Client constructor using a file:// scheme in the URL. Since Suds uses urllib2 for the HTTP transport, this is perfectly legit.

Now, because you're not providing a hostname in your WSDL URL, you will also have to pass a location argument specifying the actual URL of the SOAP application.

Here is an example:

from suds.client import Client

# The service URL
soap_url = 'http://myapp.example.notreal/path/to/soap'

# The WSDL URL, we wont' use this but just illustrating for example. This 
# would be the file you download to your system and save as wsdl_file
wsdl_url = 'http://myapp.example.notreal/path/to/soap?wsdl' 

# The full path to the downloaded WSDL file on your local system
wsdl_file = '/path/to/myapp.wsdl'
wsdl_url = 'file://' + wsdl_file # Override original wsdl_url

client = Client(url=wsdl_url, location=soap_url)

If you're interested, I have used this approach in my work and have open sourced the code.

Caching your WSDL

The other option is to use Suds' excellent caching feature. You must explicitly create a cache object and then pass that to the constructor using the cache argument. Otherwise it defaults to an ObjectCache with a duration of 1 day.

You might also consider using both of these approaches.

Fahy answered 21/10, 2011 at 17:23 Comment(2)
Ok, I will stick with suds then and use the methods you implied. Also I will probably end up with a patched version of studs, to reduce the memory footprint.Persimmon
I look forward to seeing the final outcome if you choose to share it! :)Fahy
M
12

There is new well maintained SOAP client called zeep. It supports both Python 2 and 3 and is based upon well known lxml and requests libraries.

Mowery answered 13/5, 2016 at 10:42 Comment(3)
I'm not sure I would use zeep cause their examples on the front page are flawed; first impressions. Specifically from the quick example (repeated in the other examples), the import is from zeep import Client. Then on line 2 (client = zeep.Client() would give you NameError: name 'zeep' is not defined.Procarp
Haha i was about to send PR with that change. You beat me :)Mowery
I would be careful before choosing zeep. Documentation is absolutely bad and it keeps giving 'got an unexpected keyword argument' countless times. I tried raw requests module and POST call with raw XML and it works. Seems like zeep failed me.Jemy
S
7

An interesting up-to-date post can be found here: What SOAP client libraries exist for Python, and where is the documentation for them? Unfortunately, the perfect SOAP library you are looking for seems not to exist (yet)

Sarcoid answered 18/10, 2011 at 15:3 Comment(2)
I know about this thread, this is how I stumbled upon suds in the first place. Thanks anyway.Persimmon
Also, I am not looking for a perfect library. I just need to decide if a base a bigger project I will be working on for next half year on suds. And if I have to patch the library to make it work.Persimmon
F
5

It's 2013. This is an update for anyone who encountered the problem with Python and SOAP like me.

I was trying to use SOAP in Python. I tried out suds, but sadly the library hasn't been updated since 2010. In the first test run of my code, I received this error:

RuntimeError: maximum recursion depth exceeded while calling a Python object

Which turns out to be an issue suds has with recursive references on HTTPS connections. See drfence's answer. I had to manually patch suds to get past that issue.

I switched to php instead. Not as straightforward as python, but I was able to get it working.

Firetrap answered 24/5, 2013 at 19:5 Comment(1)
I had the same issue with recursion depth loading the NetSuite WSDL. You need the latest JURKO SUDS developer build, and it should fix the issue. (Add the https before the bitbucket url - cant do it in the comments) sudo pip install bitbucket.org/jurko/suds/get/tip.tar.gz#egg=sudsLegg

© 2022 - 2024 — McMap. All rights reserved.