Is it possible to cache a python suds client?

2020-07-18 04:50发布

问题:

I'm currently running python suds against a wsdl file and its corresponding 50+ xsd files. The following call to Client takes about 90 seconds:

from suds.client import Client
url = 'http://localhost:7080/webservices/WebServiceTestBean?wsdl'
client = Client(url)

After I run the last line above, I get a Client instance. Creating that client takes a long time. Does caching work with Python objects or is it restricted to primitives like strings and integers?

Here's what I want to do in code, the syntax is wrong but it's to convey what I want:

from suds.client import Client


if 'current_client' in cache:
    client = cache.get('current_client')
else:
    url = 'http://localhost:7080/webservices/WebServiceTestBean?wsdl'
    client = Client(url)
    cache.put('current_client', client)

回答1:

suds caches WSDL and XSD files for a day by default so that each instantiation of a Client object doesn't require a separate URL request.

90 seconds seems like a really long time, is that time spent waiting on the wsdl response, or is it spent parsing the wsdl? If it's taking that long to parse it, the built-in caching isn't going to help much.

I've done something like this before, but instead of the singleton pattern, I just used a module-level global dictionary. It's the singleton pattern without all the class noise.

Something like this:

from suds.client import Client

_clients = {}

def get_client(name):
    if name not in _clients:
        _clients[name] = Client(url_for_name)
    return _clients[name]


回答2:

if i understand well your problem i think you don't want to create each time a new Client() and that you want to put in a cache so you can retrieve it ; but i think that you're complicating thing and i will suggest using the singleton pattern this will allow you to create only one instance of the client and every time you want to create an new instance it will just return the old instance that was created.

Here is an example that can help you understand what i'm suggesting.

class MyClient(Client):

    __instance__ = None

    def __new__(cls, *args, **kws):
        if not cls.__instance__:
            cls.__instance__ = super(Client, cls).__new__(cls, *args, **kws)
        return cls.__instance__

N.B: i wanted to use the borg pattern which is like singleton but more beautiful but i wasn't able to figure out how to not call Super.init (which take a long time) and in the mean time sharing the same state, if some one has a better idea of how to put it using the Borg pattern it will be great , but i don't think borg pattern can be useful in this case

Hope this can help



回答3:

suds >= 0.3.5 r473 provides some URL caching. By default, http get(s) such as getting the WSDL and importing XSDs are cached.