Question

I'm using suds to make SOAP requests to a third-party API.

import suds.client
client = suds.client.Client(WSDL_URL, location=SERVICE_URL)

When I try to create an object for a particular type defined by the WSDL (say TheObject):

obj = client.factory.create('TheObject')

I'm getting an error about it not existing:

(TheObject) not-found
path: "TheObject", not-found
Traceback (most recent call last):
  File "suds_test.py", line 67, in <module>
    sys.exit(main(sys.argv))
  File "suds_test.py", line 51, in main
    obj = client.factory.create('TheObject'),
  File "/usr/local/lib/python2.7/dist-packages/suds/client.py", line 234, in create
    raise TypeNotFound(name)
suds.TypeNotFound: Type not found: 'TheObject'

So I print the list of available suds factory types with print(client):

Suds ( https://fedorahosted.org/suds/ )  version: 0.4 GA  build: R699-20100913

Service ( OrderService ) tns="http://api.example.com/services/"
   Prefixes (2)
      ns0 = "http://api.example.com/contracts/stuff"
      ns1 = "http://api.example.com/services/"
   Ports (2):
      (OrderServiceSoap)
         Methods (123):
            ... Not really relevant
         Types (123):
            SomeType
            SomeType2
            ns0:AnotherType
            ns0:AnotherType2
            ns0:TheObject
            ...

So it appears that ns1 is the default namespace, and ns0 is the namespace I want to use for TheObject. If I prefix it with the namespace alias it works.

obj = client.factory.create('ns0:TheObject')

I would prefer not to have to remember to use ns0 in this particular case because its vary arbitrary. I looked up the docs for Factory.create() but it only accepts a single argument name with no additional arguments for namespace URL or anything.

Is there a way to dynamically determine the namespace for TheObject? Or is it possible to specify the whole URL for ns0 instead of just the namespace alias? Any help would be appreciated.

Was it helpful?

Solution

And it should have been painfully obvious to me that it is a standard XML namespace, and it's clearly indicated in the documentation (which I missed).

To specify the namespace by URL you simply prefix the name with the namespace URL wrapped in {} (curly braces):

obj = client.factory.create('{http://api.example.com/contracts/stuff}TheObject')
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top