Search code examples
pythonsoapwsdlsuds

Is there a way to provide an external WSDL file to a Python Suds client


I am working with a SOAP service where the project provides an external WSDL file. I am using Python + Suds to connect to the service. I run into issues because the (https) service URL looks like:

/sipxconfig/services/UserService?wsdl

But the WSDL ath that URL does not match the external WSDL file that is provided by the project. The SOAP document returned does match the external WSDL file. So my suds client raises a fault.

I have so far managed to work around this by writing a suds plugin to "correct" the SOAP XML returned so that it matches the dynamically created WSDL (at the URL). However, I was hoping there was a way to feed the subs client the external WSDL file and then switch it to using the URL for the service.

I tried something like this:

wsdl_file = os.path.abspath(args.wsdl_file)
client = Client("file://%s" % wsdl_file, transport=t, username=sip_user, password=sip_pwd, doctor=doctor)
client.set_options(location=url)

#Get the results.
user_search = client.factory.create("UserSearch")
user_search.byUserName = args.find_user
user_search.byFuzzyUserNameOrAlias = args.fuzzy
user_search.byGroup = args.group

result = client.service.findUser(user_search)
#^^^
#Error here!

But it ultimately results in a MethodNotFound exception. I run netstat in another terminal, and I can see that the client is not making a network connection to the external service.

Has anyone else managed to feed Suds WSDL from a file?

Thanks, Carl


Solution

  • So I determined I was on the correct track, but my SOAP service had multiple ports. I needed to do the following:

    wsdl_file = os.path.abspath(args.wsdl_file)
    client = Client("file://%s" % wsdl_file, transport=t, username=sip_user, password=sip_pwd, doctor=doctor)
    client.set_options(location=url)
    
    #Get the results.
    user_search = client.factory.create("UserSearch")
    user_search.byUserName = args.find_user
    user_search.byFuzzyUserNameOrAlias = args.fuzzy
    user_search.byGroup = args.group
    
    result = client.service['UserService'].findUser(user_search)
    #                      ^^^^^^^^^^^^^^^
    # This was the missing bit that threw me off!
    

    Thanks, Carl