python-zeep icon indicating copy to clipboard operation
python-zeep copied to clipboard

Caching built WSDL

Open rossgray opened this issue 8 years ago • 8 comments

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!

rossgray avatar Nov 08 '17 10:11 rossgray

👍

renatovico avatar Nov 08 '17 14:11 renatovico

@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

renatovico avatar Nov 08 '17 14:11 renatovico

@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.

rossgray avatar Nov 08 '17 16:11 rossgray

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

mvantellingen avatar Nov 13 '17 20:11 mvantellingen

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)

rossgray avatar Nov 14 '17 11:11 rossgray

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?

acidjunk avatar Nov 28 '17 09:11 acidjunk

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)

mvantellingen avatar Dec 19 '17 17:12 mvantellingen

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

  • Transport object: can have InMemoryCache or SqliteCache
  • This transport object can be pass to zeep.CachingClient

abhishakegupta91 avatar Apr 26 '24 13:04 abhishakegupta91