4

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)
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
Thierry Lam
  • 45,304
  • 42
  • 117
  • 144

3 Answers3

4

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]
Don Spaulding
  • 764
  • 5
  • 13
  • 2
    I have the wsdl and its corresponding xsd files locally on the same machine as the scripts. I read them directly from the file system. Fetching the wsdl file is fast, parsing it is slow. I think the issue with suds is that it doesn't generate any code from the wsdl compared to soap frameworks from Java. suds might be good for lightweight wsdl files but not the big one. – Thierry Lam Nov 03 '10 at 23:25
  • 2
    Yeah, if you're loading them from files, parsing is the bottleneck. I still don't see why you wouldn't use suds, with a trick like above, and just "prime the pump". That is, on startup, run through every client name and call `get_client(name)` on it, so by the time the first request comes in, you've already loaded and parsed all the clients. – Don Spaulding Nov 04 '10 at 23:40
  • 1
    @ThierryLam, you may have also hit the same problem I did, which is that: [Suds is not reusing cached WSDLs and XSDs, although I expect it to](http://stackoverflow.com/questions/6038226/suds-is-not-reusing-cached-wsdls-and-xsds-although-i-expect-it-to) – Mike M. Lin Mar 17 '12 at 00:14
0

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

panchicore
  • 11,451
  • 12
  • 74
  • 100
0

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

mjallday
  • 9,796
  • 9
  • 51
  • 71
mouad
  • 67,571
  • 18
  • 114
  • 106
  • Is the single pattern valid when it comes to web applications? Wouldn't each http request create a new instance of Client on the first call? I want the Client object to be persistent for a long time. – Thierry Lam Nov 03 '10 at 21:16
  • @Thierry Lam: __Is the single pattern valid when it comes to web applications?__ yes why it shouldn't ? __Wouldn't each http request create a new instance of Client on the first call?__ yes that the idea when it come to creating a new instance if you have already creating one it will just return the old instance without having to reproduce it , like you said if "the first" http request create an instance of Client the second time that a new http request will try to create a new instance of the class, __Client__ will just return the old instance that was created before, so no reconnecting ... – mouad Nov 03 '10 at 21:23
  • When I use the Singleton pattern to create Client and put it in a python script, __instance__ is still None during each fresh new run of the python script. The singleton pattern doesn't work if I want many calls of a python script to call the same processed Client object. – Thierry Lam Nov 03 '10 at 21:38
  • @Thierry Lam: it weird that "__instance__" was still None check my edit , sorry that i didn't test the code before i put it , and this one is also not tested (don't have any valid wsdl url) :), hope this can help you. – mouad Nov 03 '10 at 22:13