mvantellingen / python-zeep

A Python SOAP client
http://docs.python-zeep.org
Other
1.9k stars 586 forks source link

Caching built WSDL #612

Open rossgray opened 7 years ago

rossgray commented 7 years ago

Hi,

We are using zeep in a Flask application and are creating a new zeep client for each incoming request. We have found that it is very slow to initialise the zeep client each time (even with using the SqliteCache). The reason for this is that is takes a very long time (several seconds) to parse the WSDL (specifically, creating the Definition), which is very large.

Do you have any suggestions on the best way to handle this? We could, of course, create a global instance of the zeep client (ensuring this is thread safe). It would be preferable if there were a way to cache the built wsdl object, assuming this is feasible?

Thanks!

renatovico commented 7 years ago

👍

renatovico commented 7 years ago

@rossgray the best combination for me is gevent + flask + redis and "deepcopy the zeep instance " this is not cool, but worked for 50 req/s

But cache zeep definition it the better way

rossgray commented 7 years ago

@renatoelias can you elaborate on how you did the "deepcopy the zeep instance"? I tried to pickle the zeep instance and just the zeep definition, but I got a pickling error.

mvantellingen commented 7 years ago

The zeep object should be thread-safe, so you should be able to reuse that for multiple requests. The only thing i'm worrying about is the request session object (used in the transport).

Caching the definitions (pickling?) is perhaps doable but i don't think it is necessary

rossgray commented 7 years ago

The main issue I was running into was that I needed to set a soap header for each request (basically setting a session ID), which didn't appear to be thread-safe (they're stored as state inside the zeep client)

acidjunk commented 6 years ago

I'm converting a flask app from Suds to Zeep and I must say: I am impressed by the ease of use and speed of Zeep. Reading this thread worries me a bit: for the Suds solution we used a ConnectionPool that contained complete Suds clients to ensure speed. I think I like @renatoelias deepcopy solution but I am not sure what to do to ensure thread safety. Anyone willing to share some code regarding best practices for a threaded solution?

mvantellingen commented 6 years ago

Ah yes, when you set default soap headers on the client object then that isn't thread safe indeed. Need to fix that.

You can also pass in soap headers explicitly for each operation, that should be thread safe currently.

EDIT: I think it is thread safe, but the default soap headers are used for each client in your case. So the explicit options is the best here (or we need to do it via a context manager)

abhishakegupta91 commented 7 months ago

Here is an example of using Caching with Zeep. https://docs.python-zeep.org/en/master/transport.html#caching