Git Product home page Git Product logo

suds's People

Contributors

admin-schreurs avatar apkawa avatar bouke avatar brccabral avatar btb avatar cjmayo avatar eshizhan avatar frost-nzcr4 avatar gopackgo90 avatar graingert avatar grzn avatar guifran001 avatar ivavi9 avatar jurko-gospodnetic avatar mduggan avatar oalbrigt avatar palday avatar phillbaker avatar riturajsingh878 avatar sbraz avatar sebromon avatar stephenfin avatar swt2c avatar thedyrn avatar timgates42 avatar timsavage avatar waynesun09 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

suds's Issues

Suds client use wrong port for webservice

we have haproxy + webservice server.

  1. when our haproxy use 8081 port --> webservice, suds client can't connect to the server
    server = Client("http://ourproxy:8081/CL3/webservice.asmx?wsdl")

  2. when our haproxy use 80 port --> webservice, suds client get service correctly.
    we can use server = Client("http://ourproxy:8081/CL3/webservice.asmx?wsdl") or server = Client("http://ourproxy:80/CL3/webservice.asmx?wsdl") to get service.

after debug with wireshark, we found Client always use port 80 to request service.

could you please check this?

Service description's namespaces breaks implementation on adding namespaces

ServiceDescription sorts the namespaces as retrieved from the wsdl/xsds, here:

namespaces.sort()

However, if a service owner updates the wsdl to add a namespace (in what they believe is a backward compatible way), sorting the namespaces alphabetically may re-order the namespaces. E.g.:

-    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="urn:ws:foo:com:tns:v1_00" xmlns:ns1="urn:ws:foo:com:bar:old:v1_00" elementFormDefault="qualified" targetNamespace="urn:ws:foo:com:common:v1_00">
+    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"  xmlns:tns="urn:ws:foo:com:tns:v1_00" xmlns:ns2="urn:ws:foo:com:bar:new:v1_00"  xmlns:ns1="urn:ws:foo:com:bar:old:v1_00" elementFormDefault="qualified" targetNamespace="urn:ws:foo:com:common:v1_00">
        <xs:import namespace="urn:ws:eplinc:com:cgs:old:v1_00" />
+        <xs:import namespace="urn:ws:eplinc:com:cgs:new:v1_00" />
</xs:schema>

Code like:

client = Client(...)
client.factory.create('ns1:MessageHeader')  # using the urn:ws:foo:com:bar:old namespace

Will break at runtime, because it's resorted to ns2 alphabetically (after the urn:ws:foo:com:bar:new namespace). It has to be updated to:

client.factory.create('ns2:MessageHeader')  # using the urn:ws:foo:com:bar:old namespace

Proposal: because simply deleting the sorting will also re-order the namespaces in a backwards-incompatible manner, move this sorting to be behind an option that is true by default, but can be turned off; in the next major release, make this false by default.

What is "_WObject__resolved = False" and what is it's function in WSDL?

Hi

I am neither an IT-professional nor SOAP proficient, but have been using SUDS-jurko for some years to connect to a system.

We are trying to use newer versions of python, and still need to use suds. We were very happy to find this project, but struggle to interact via suds interpretation of WSDL due to the new entry _Wobject__resolved = False

For us, it means the suds.client.factory.create('GetByPathAndCode') does not return the values we expected.

I have tried to play around with the source a bit without getting any real progress and post it here in case it is an issue for others as well.

The wsdl is quite large, so for illustration I will post the difference between the two outputs I get from suds.client.wsdl and one operation:

python 3.10 and suds 1.0
Feedback from print(suds.client.wsdl):

 GetByPathAndCode = 
      (Operation){
         name = "GetByPathAndCode"
         tns[] = 
            "tns",
            "http://www.powel.com/TimeSeries/2013/01",
         input = 
            (Message){
               _WObject__resolved = True
               name = "TimeSeriesFullNameMessageContract"
               qname = "(TimeSeriesFullNameMessageContract, http://www.powel.com/TimeSeries/2013/01)"
               parts[] = 
                  (Part){
                     root = <wsdl:part name="parameters" element="tns:TimeSeriesFullNameMessageContract"/>
                     _WObject__resolved = False
                     name = "parameters"
                     qname[] = 
                        "parameters",
                        "http://www.powel.com/TimeSeries/2013/01",
                     element = "('TimeSeriesFullNameMessageContract', 'http://www.powel.com/TimeSeries/2013/01')"
                     type = "None"
                  },
            }
         output = 
            (Message){
               _WObject__resolved = True
               name = "TimeSeriesMessageContract"
               qname = "(TimeSeriesMessageContract, http://www.powel.com/TimeSeries/2013/01)"
               parts[] = 
                  (Part){
                     root = <wsdl:part name="parameters" element="tns:TimeSeriesMessageContract"/>
                     _WObject__resolved = False
                     name = "parameters"
                     qname[] = 
                        "parameters",
                        "http://www.powel.com/TimeSeries/2013/01",
                     element = "('TimeSeriesMessageContract', 'http://www.powel.com/TimeSeries/2013/01')"
                     type = "None"
                  },
            }
         faults[] = <empty>
      }

python 3.10 and suds 1.0
Feedback from client.factory.create('GetByPathAndCodesRequestDataContract'):

(GetByPathAndCodesRequestDataContract){
   Identities = None
 }

python 3.7 and suds-jurko 0.6:
Feedback from print(suds.client.wsdl):

GetByPathAndCode = 
    (Operation){
       name = "GetByPathAndCode"
       tns[] = 
          "tns",
          "http://www.powel.com/TimeSeries/2013/01",
       input = 
          (Message){
             name = "TimeSeriesFullNameMessageContract"
             qname = "(TimeSeriesFullNameMessageContract, http://www.powel.com/TimeSeries/2013/01)"
             parts[] = 
                (Part){
                   root = <wsdl:part name="parameters" element="tns:TimeSeriesFullNameMessageContract"/>
                   name = "parameters"
                   qname[] = 
                      "parameters",
                      "http://www.powel.com/TimeSeries/2013/01",
                   element = "('TimeSeriesFullNameMessageContract', 'http://www.powel.com/TimeSeries/2013/01')"
                   type = "None"
                },
          }
       output = 
          (Message){
             name = "TimeSeriesMessageContract"
             qname = "(TimeSeriesMessageContract, http://www.powel.com/TimeSeries/2013/01)"
             parts[] = 
                (Part){
                   root = <wsdl:part name="parameters" element="tns:TimeSeriesMessageContract"/>
                   name = "parameters"
                   qname[] = 
                      "parameters",
                      "http://www.powel.com/TimeSeries/2013/01",
                   element = "('TimeSeriesMessageContract', 'http://www.powel.com/TimeSeries/2013/01')"
                   type = "None"
                },
          }
       faults[] = <empty>
    }

python 3.7 and suds-jurko 0.6:
Feedback from client.factory.create('GetByPathAndCodesRequestDataContract')

(GetByPathAndCodesRequestDataContract){
   Identities = 
      (ArrayOfTimeSeriesFullNameDataContract){
         TimeSeriesFullNameDataContract[] = <empty>
      }
 }

Is there a way to make suds 1.0 behave in the same manner as suds-jurko in interpreting this wsdl or an approach to try to remove _WObject__resolved = False to see if that this is indeed the problem?

I can supply the full wsdl if it is of interest.

Suds returning method instead of value

I am attempting to connect SOAP API with Python. I am using Py3.9 version. I am using a simple method that returns the time on server and we don't need to pass any parameter ,as shown below:

servertime()
If I use SOAP UI for the method I can get the values directly in XML hour, minute , timezone etc.
Code :

from suds.client import Client
operation_OA = Client("server-address/wsdl.pl?")
server_time = getattr(operation_OA.service, "servertime")
print(server_time())

I get the below error: suds.TypeNotFound: Type not found: 'timezone' Can anyone suggest.

Going through all the logs I found out that somehow the server_time() returns a method . (Just to understand I used a For loop). My understanding is that it would return the output of a method instead.

for oa in server_time:
    print(oa)

This is what I get : TypeError: 'Method' object is not iterable. What am I missing ?

AttributeError: 'Document' object has no attribute 'set'

Hi,
I'm adding this issue here to speed up the process, I don't believe it's a suds bug, so that's more like a question.
I'm processing some shipment GLS API to, close shipment with the format like:

<info>
 <SedeGls>XX</SedeGls>
 <CodiceClienteGls>xxx</CodiceClienteGls>
 <PasswordClienteGls>xxx</PasswordClienteGls>
 <Parcel>
   <NumeroDiSpedizioneGLSDaConfermare>11111111</NumeroDiSpedizioneGlsDaConfermare>
 </Parcel>
</info>

Here I get an error:

[2021-12-14 11:48:27,472] {log.py:224} ERROR - Internal Server Error: /gls/process
Traceback (most recent call last):
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 179, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/rest_framework/decorators.py", line 50, in handler
    return func(*args, **kwargs)
  File "/home/corrieri/corrieri/Palumbix/Palumbix/views.py", line 96, in glsProcessShipment
    response = close_shipments_by_number(account.SedeGls,
  File "/home/corrieri/corrieri/Palumbix/gls/utils.py", line 52, in close_shipments_by_number
    response = sp.service.CloseWorkDayByShipmentNumber(data)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/suds/client.py", line 566, in __call__
    return client.invoke(args, kwargs)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/suds/client.py", line 703, in invoke
    soapenv = binding.get_message(self.method, args, kwargs)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/suds/bindings/binding.py", line 122, in get_message
    content = self.bodycontent(method, args, kwargs)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/suds/bindings/document.py", line 95, in bodycontent
    parse_args(method.name, self.param_defs(method), args, kwargs,
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/suds/argparser.py", line 83, in parse_args
    return arg_parser(args, kwargs, extra_parameter_errors)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/suds/argparser.py", line 108, in __call__
    self.__process_parameters()
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/suds/argparser.py", line 299, in __process_parameters
    self.__process_parameter(*pdef)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/suds/argparser.py", line 293, in __process_parameter
    self.__external_param_processor(param_name, param_type,
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/suds/bindings/document.py", line 87, in add_param
    p = self.mkparam(method, pdef, value)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/suds/bindings/document.py", line 129, in mkparam
    return super(Document, self).mkparam(method, pdef, object)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/suds/bindings/binding.py", line 244, in mkparam
    return marshaller.process(content)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/suds/mx/core.py", line 55, in process
    self.append(document, content)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/suds/mx/core.py", line 68, in append
    self.appender.append(parent, content)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/suds/mx/appender.py", line 86, in append
    appender.append(parent, content)
  File "/home/corrieri/corrieri/venv/lib/python3.9/site-packages/suds/mx/appender.py", line 179, in append
    parent.set(attr, value)
AttributeError: 'Document' object has no attribute 'set'

That's raised in the PrimitiveAppender class from suds/mx/appender.py

 class PrimitiveAppender(Appender):
     """
     An appender for python I{primitive} types.
     """
 
     def append(self, parent, content):
         if content.tag.startswith('_'):
             attr = content.tag[1:]
             value = tostr(content.value)
             if value:
                 parent.set(attr, value)
         else:
             child = self.node(content)
             child.setText(tostr(content.value))
             parent.append(child)
<s:element name="CloseWorkDay">
        <s:complexType>
           <s:sequence>
              <s:element minOccurs="0" maxOccurs="1" name="XMLCloseInfoParcel" type="s:string"/>
           </s:sequence>
        </s:complexType>
</s:element>
<s:element name="CloseWorkDayByShipmentNumber">
        <s:complexType>
           <s:sequence>
              <s:element minOccurs="0" maxOccurs="1" name="_xmlRequest" type="s:string"/>
           </s:sequence>
        </s:complexType>
</s:element>

The difference I see up here with these two methods,

  • CloseWorkDay
  • CloseWorkDayByShipmentNumber

The name is "_xmlRequest"

Here parent is a suds.sax.document.Document object and indeed it doesn't have a set method as this class doesn't extend the suds.sax.element.Element class, which I believe should be there instead.

It doesn't seems my XML request is wrong, I don't get it.
Do you have any hints?

warnings when building docs in python3 compatibility

If you are using Sphinix for python3.x when building the documentation, you will see a couple of warnings about syntax errors in suds' code.
If the purpose is to maintain 2.7 compatibility, some modifications are needed to ensure compatibility as well as to avoid such warnings. Otherwise it's just a matter of syntax.
Whatever the case, I can take care of that.

*** File "./suds/xsd/query.py", line 57
raise Exception, 'not-implemented by subclass'

raise Exception, 'not-implemented by subclass'

and so on...
*** File "./suds/xsd/sxbasic.py", line 671
raise Exception, "%s mismatch" % TNS
*** File "./tests/external/axis1.py", line 171
except WebFault, f:
*** File "./tests/external/jasper.py", line 38
except WebFault, f:
*** File "./tests/external/public.py", line 65
except WebFault, f:
*** File "./tests/external/rhq.py", line 109
except WebFault, f:
*** File "./tests/external/saxenc.py", line 29
print 'A(parsed)=\n%s' % a

How to assemble parameters in CDATA

My request parameter xml is:

<soapenv:Envelope
xmlns:soapenv=http://schemas.xmlsoap.org/soap/envelope/
xmlns:erp=http://xmlns.oracle.com/Enterprise/Tools/schemas/CST_INF_REQ.V1">
<soapenv:Header/>
<soapenv:Body>
<erp:REQUEST>
<erp:BATCH_NUM>xxx</erp:BATCH_NUM>
<erp:IFAC_CODE>xxx</erp:IFAC_CODE>
<erp:REQUEST_DATA>
<![CDATA[
<ROOT>
<CST_PAGENUMBER>xxx</CST_PAGENUMBER>
<CST_PAGESIZE>xxx</CST_PAGESIZE>
<RUN_TYPE>xxx</RUN_TYPE>
<TOKENID>xxx</TOKENID>
<SYSTEM>xxx</SYSTEM>
</ROOT>]]>
</erp:REQUEST_DATA>
</erp:REQUEST>
</soapenv:Body>
</soapenv:Envelope>

The method the client sees is

CST_INF_JOBCODE_OUT(xs:string BATCH_NUM, xs:string IFAC_CODE, xs:string REQUEST_DATA, )

My code:

from suds.client import Client

url = "http://172.19.1.7/PSIGW/PeopleSoftServiceListeningConnector/PSFT_HR/CST_INF_SERVICE.13.wsdl"
client = Client(url)
print(client)
testParam = {
    "BATCH_NUM": "xxx",
    "IFAC_CODE": "xxx",
    "REQUEST_DATA": {
        "CST_PAGENUMBER": 100,
        "CST_PAGESIZE": 1,
        "RUN_TYPE": "ALL",
        "TOKENID": "xxx",
        "SYSTEM": "xxx",
    },
}
result = client.service.CST_INF_JOBCODE_OUT(**testParam)
print(result)

This request is wrong, but how should I write the parameters in REQUEST_DATA?

Handling of xsd:anytype

Hi,

I am using suds to communicate with our Polarion Server to read/write Polarion Work Items (Work Item: Polarion object).
The Work Item data structure contains a custom field which is of type "ArrayOfCustom".
This array contains elements of type "Custom" as shown below:

<complexType name="Custom">
    <sequence>
        <element name="key" type="xsd:string"/>
        <element name="value" nillable="true"/>
    </sequence>
</complexType>
<complexType name="ArrayOfCustom">
    <sequence>
        <element maxOccurs="unbounded" minOccurs="0" name="Custom" type="tns3:Custom"/>
    </sequence>
</complexType>

For "Custom.value", no type is defined as it can be different for each custom field entry.
This was no problem so far as the types used for "value" were strings or enums.
Now, I added the custom field "lastTestRunDatetime" of type "xsd:dateTime".
When I read the Work Item form the server, I get the following SOAP data transfer:

<ns3:customFields>
   <ns3:Custom>
      <ns3:key>lastTestRunString</ns3:key>
      <ns3:value xsi:type="xsd:string">2021-03-26 12:36</ns3:value>
   </ns3:Custom>
   <ns3:Custom>
      <ns3:key>lastTestRunDatetime</ns3:key>
      <ns3:value xsi:type="xsd:dateTime">2021-04-07T09:00:00.000Z</ns3:value>
   </ns3:Custom>
   <ns3:Custom>
      <ns3:key>lastTestResult</ns3:key>
      <ns3:value xsi:type="ns3:EnumOptionId">
         <ns3:id xsi:type="xsd:string">passed</ns3:id>
      </ns3:value>
   </ns3:Custom>
</ns3:customFields>

i.e. the value for "lastTestRunDatetime" is transfered in the "xsd:dateTime" format.

Sending the same data back to the server, results in following SOAP data transfer:

<ns0:customFields>
  <ns0:Custom>
    <ns0:key>lastTestRunString</ns0:key>
    <ns0:value>2021-03-26 12:36</ns0:value>
  </ns0:Custom>
  <ns0:Custom>
    <ns0:key>lastTestRunDatetime</ns0:key>
    <ns0:value>2021-04-07 09:00:00+00:00</ns0:value>
  </ns0:Custom>
  <ns0:Custom>
    <ns0:key>lastTestResult</ns0:key>
    <ns0:value><ns0:id>passed</ns0:id></ns0:value>
  </ns0:Custom>
</ns0:customFields>

i.e the value for "lastTestRunDatetime" changed from
"2021-04-07T09:00:00.000Z"
to
"2021-04-07 09:00:00+00:00".
which results in the server error "java.lang.NumberFormatException: Invalid date" (The " " instead of "T" is causing this error).

As this works for other fields that have the "xsd:dateTime" in the WSDL description, I did a bit of debugging:
As value has no type specified in the WSDL description, the lastTestRunDatetime value is serialized via the regular Python data type "dateTime.dateTime" string conversion. For fields that are specified as "xsd:dateTime", the data type "suds.sax.date.Datetime" is used for the string conversion which calls .isoformat() to do the string conversion.

Is there a way to change this behavior at application level, e.g. by setting the type for value from "xsd:anyType" to "xsd:dateTime"?

If not, what would be the best way to patch the suds library? After a bit of debugging, I see the following possibility:

  • Patch class Xany (in sxbuiltin.py):
    Add a translate() method which does the XDateTime() processing in case "isinstance(value, datetime.datetime)".

But this looks like a brute force approach. I would rather prefer to change the "type determination" when node "lastTestRunDatetime" is processed.

Any ideas how to solve this in a clean way without breaking other suds based applications?

Regards,
Oliver

onvif 0.2.0 depends on suds>=0.4

I am trying to install onvif in my Django project.
it depends on suds.

i try to reinstall suds by pip, output -
Requirement already satisfied: suds in /home/dip05/anaconda3/lib/python3.7/site-packages (0.3.5)

how I can I solve it, and upgrade

Headers passed into suds.client.Client() are not used in WSDL and XSD requests

suds.client.Client() allows you to pass in custom HTTP headers to be used in the requests to the SOAP webservice

For example:

suds.client.Client(url, headers={'Host': '127.0.0.1'})

This will correctly set the Host HTTP header for SOAP operation requests. However, it will not correctly set the Host HTTP for the initial WSDL and subsequent XSD requests.

This can be problematic if the webservice requires a specific HTTP header for all requests (including the initial WSDL load).

It looks like this is where we would need to add the headers for the WSDL request

suds/suds/reader.py

Lines 165 to 196 in c94298c

def __fetch(self, url):
"""
Fetch document content from an external source.
The document content will first be looked up in the registered document
store, and if not found there, downloaded using the registered
transport system.
Before being returned, the fetched document content first gets
processed by all the registered 'loaded' plugins.
@param url: A document URL.
@type url: str.
@return: A file pointer to the fetched document content.
@rtype: file-like
"""
content = None
store = self.options.documentStore
if store is not None:
content = store.open(url)
if content is None:
request = suds.transport.Request(url)
fp = self.options.transport.open(request)
try:
content = fp.read()
finally:
fp.close()
ctx = self.plugins.document.loaded(url=url, document=content)
content = ctx.document
sax = suds.sax.parser.Parser()
return sax.parse(string=content)

And here for the subsequent XSD requests

suds/suds/xsd/sxbasic.py

Lines 587 to 598 in c94298c

def __download(self, url, loaded_schemata, options):
"""Download the schema."""
try:
reader = DocumentReader(options)
d = reader.open(url)
root = d.root()
root.set("url", url)
return self.schema.instance(root, url, loaded_schemata, options)
except TransportError:
msg = "import schema (%s) at (%s), failed" % (self.ns[1], url)
log.error("%s, %s", self.id, msg, exc_info=True)
raise Exception(msg)

Change the value of "elementFormDefault"

Recently we needed to set the value of elementFormDefault from qualified to unqualified because of third-party requirements. However, I didn't find any related line about that after a quick look into your guide. Does anyone describe a possible solution?

Upload source archive to PyPI

The only wheel on pypi is for python 3, so soap-community can't be installed on 2.7. PyPI ought to at at least have the source archive (.tar.gz) which will make this possible.

ResourceWarning: unclosed file in reader.py

This warning is showing when run whith python -Wa

python3.7/site-packages/suds/reader.py:72: ResourceWarning: unclosed file <_io.BufferedReader name='/tmp/suds/suds-***-document.px'>

Non-standard service name

Cannot call a service with non-standard service name (example: client.service.wsExtAuth..ckAuth).

Tried with this solution but got this error:

SAXParseException: :77:13: not well-formed (invalid token)

Does suds support this security implementation?

Hi, i'm trying to send message to a SOAP server with some confusing security layer and I want to see if SUDS has the way to implement this:
I've been provided with some public and private keys, a certificate and a JKS file.
I have the instructions to make it work in SOAPUI, apparently I need to encrypt the body of the message with this settings:
image
And also add a SHA1 signature
image
Along side a timestamp element.

Can SUDS make this work? any help is greatly appreciated.

Breaking behavior change was introduced in Jurko unreleased code

The following commit
b6d1d09
introduced a behavior change that breaks code that was using suds-jurko 0.6.

Since, this code was never released, I wonder if the commit could be reverted.
Originally, it was to fix this problem:
https://bitbucket.org/jurko/suds/issues/81

The original behavior was (suds-jurko 0.6):
When creating a sudsojbect.Object this way: client.factory.create("myObjectr"), the instanciated object has all its optional attributes were set to None and not added into the payload when calling a service with this object as argument.

The new behavior is (suds-community):
When creating a sudsojbect.Object this way: client.factory.create("myObject"), the instantiated object has all its optional attributes set. When calling a service with with this object as argument will result with having those optional attributes in the payload as .

I don't think the new behavior is correct, because if one updates a SOAP service to add an optional attribute to an object, it is absurd that all the clients using suds will start to add it by default and therefore change the expected behavior (the absence of an optional attribute is different than the presence of an empty attribute (for the server we are using at least)).

I've not been able to think of a solution for the original issue though, but it should not be fixed like that.

Can the commit be reverted ?

Missing array compared to suds-jurko

We recently evaluated switching to suds-community from suds-jurko and found a compatibility problem. Elements that were previous populated with empty lists are now set to None. Here's the comparison:

suds-community gives this:

    (PostLedgerRequest){
       TokenId = None
       Payments = None
       Charges = None
       Refunds = None
       Voids = None
    }

Versus suds-jurko:

    (PostLedgerRequest){
       TokenId = None
       Payments =
          (ArrayOfPaymentInMsg){
             PaymentInMsg[] = <empty>
          }
       Charges =
          (ArrayOfChargeInMsg){
             ChargeInMsg[] = <empty>
          }
       Refunds =
          (ArrayOfRefundInMsg){
             RefundInMsg[] = <empty>
          }
       Voids =
          (ArrayOfVoidInMsg){
             VoidInMsg[] = <empty>
          }
    }

I've dug in to the problem and narrowed it down to the change in behavior due to #14, #15, and #16. Reverting the changed line (as in setattr(data, type.name, value) # if not type.optional() or type.multi_occurrence() else None)) in builder.py fixes the problem for us, but think I understand why the change was made in the first place so suspect that removing all of it is not the right solution.

My guess is that multi_occurrence() needs to look recursively into the nesting before failing. In our case the top level is optional, but the next is not.

It is also possible that we aren't using suds correctly or misunderstand the structure somehow, but I can say that the code works with sud-jurko and not with suds-community.

Although the API we are calling is not public and is controlled by a vendor, I have built the following test that demonstrates the problem. If dropped into the test suite, it should run and fail. Note that this is a pruned down and somewhat modified version of the vendor's schema and almost certainly could be simplified more. Sorry that it is a bit noisy.

It looks like incorporating parts of this into the test suite, perhaps as an expansion to the changes made for the #16 pull request would be beneficial.

We would appreciate any clarification if we are misusing suds somehow and/or confirmation that this is a bug.

Thanks! Tim

import suds
import testutils

ledger_wsdl = """<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://www.example.com/Soa/Foundation/" xmlns:s1="http://www.example.com/Soa/Foundation/MessageDefinition.xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" targetNamespace="http://www.example.com/Soa/Foundation/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <wsdl:types>
    <s:schema elementFormDefault="qualified" targetNamespace="http://www.example.com/Soa/Foundation/">
      <s:import namespace="http://www.example.com/Soa/Foundation/MessageDefinition.xsd" />
      <s:element name="PostLedger">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" ref="s1:PostLedgerRequest" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="PostLedgerResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" ref="s1:PostLedgerResponse" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="RequestHeader" type="tns:RequestHeader" />
      <s:complexType name="RequestHeader">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="Headers" type="tns:ArrayOfAnyType" />
        </s:sequence>
        <s:anyAttribute />
      </s:complexType>
      <s:complexType name="ArrayOfAnyType">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="unbounded" name="anyType" nillable="true" />
        </s:sequence>
      </s:complexType>
      <s:element name="ResponseHeader" type="tns:ResponseHeader" />
      <s:complexType name="ResponseHeader">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="Headers" type="tns:ArrayOfAnyType" />
        </s:sequence>
        <s:anyAttribute />
      </s:complexType>
    </s:schema>
    <s:schema elementFormDefault="qualified" targetNamespace="http://www.example.com/Soa/Foundation/MessageDefinition.xsd">
      <s:element name="PostLedgerRequest" type="s1:PostLedgerRequest" />
      <s:complexType name="PostLedgerRequest">
        <s:complexContent mixed="false">
          <s:extension base="s1:GenericRequest">
            <s:sequence>
              <s:element minOccurs="0" maxOccurs="1" name="Payments" type="s1:ArrayOfPaymentInMsg" />
              <s:element minOccurs="0" maxOccurs="1" name="Charges" type="s1:ArrayOfChargeInMsg" />
              <s:element minOccurs="0" maxOccurs="1" name="Refunds" type="s1:ArrayOfRefundInMsg" />
              <s:element minOccurs="0" maxOccurs="1" name="Voids" type="s1:ArrayOfVoidInMsg" />
            </s:sequence>
          </s:extension>
        </s:complexContent>
      </s:complexType>
      <s:complexType name="GenericRequest">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="TokenId" type="s:string" />
        </s:sequence>
      </s:complexType>
      <s:complexType name="ArrayOfPaymentInMsg">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="unbounded" name="PaymentInMsg" nillable="true" type="s1:PaymentInMsg" />
        </s:sequence>
      </s:complexType>
      <s:complexType name="PaymentInMsg">
        <s:complexContent mixed="false">
          <s:extension base="s1:LedgerInMsg">
            <s:sequence>
              <s:element minOccurs="1" maxOccurs="1" name="ScheduledPayment" type="s:boolean" />
              <s:element minOccurs="0" maxOccurs="1" default="false" name="AddScheduledPayment" type="s:boolean" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="EnrollmentId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="StudentAcademicYearId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="None" name="AwardYear" type="s1:AwardYearType" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="CourseId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="StudentAddressId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="AddressTypeId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="BankAccountId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="" name="CCAuthorization" type="s:string" />
              <s:element minOccurs="0" maxOccurs="1" default="" name="CCDeclineCode" type="s:string" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="CreditCardId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="-1.0" name="InterestAmount" type="s:decimal" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="FundSourceId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="StudentAidId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="" name="CheckNumber" type="s:string" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="CreditCardBatchId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="ScheduledPaymentId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="unbounded" name="PaymentDistributionMsgs" type="s1:PaymentDistributionMsg" />
              <s:element minOccurs="1" maxOccurs="1" name="PaymentType" type="s1:PaymentType" />
            </s:sequence>
          </s:extension>
        </s:complexContent>
      </s:complexType>
      <s:complexType name="LedgerInMsg">
        <s:complexContent mixed="false">
          <s:extension base="s1:GenericInMsg">
            <s:sequence>
              <s:element minOccurs="1" maxOccurs="1" name="StudentId" type="s:int" />
              <s:element minOccurs="1" maxOccurs="1" name="Amount" type="s:decimal" />
              <s:element minOccurs="1" maxOccurs="1" name="TransactionDate" type="s:dateTime" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="CampusId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" name="Description" type="s:string" />
              <s:element minOccurs="0" maxOccurs="1" default="1900-01-01T00:00:00" name="PostingDate" type="s:dateTime" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="TermId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="" name="ReferenceNumber" type="s:string" />
            </s:sequence>
          </s:extension>
        </s:complexContent>
      </s:complexType>
      <s:complexType name="GenericInMsg">
        <s:complexContent mixed="false">
          <s:extension base="s1:GenericMsg">
            <s:sequence>
              <s:element minOccurs="0" maxOccurs="1" name="MessageState" type="s:string" />
            </s:sequence>
          </s:extension>
        </s:complexContent>
      </s:complexType>
      <s:complexType name="GenericMsg">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" default="-1" name="MessageId" type="s:int" />
          <s:element minOccurs="0" maxOccurs="1" name="CustomAttributes" type="s1:ArrayOfCustomAttributeMsg" />
          <s:element minOccurs="0" maxOccurs="1" default="-1" name="CorrelationId" type="s:int" />
          <s:element minOccurs="0" maxOccurs="1" default="false" name="SkipSemanticValidation" type="s:boolean" />
        </s:sequence>
      </s:complexType>
      <s:complexType name="ArrayOfCustomAttributeMsg">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="unbounded" name="CustomAttributeMsg" nillable="true" type="s1:CustomAttributeMsg" />
        </s:sequence>
      </s:complexType>
      <s:complexType name="CustomAttributeMsg">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" />
          <s:element minOccurs="0" maxOccurs="1" name="Value" type="s:string" />
        </s:sequence>
      </s:complexType>
      <s:complexType name="GenericOutMsg">
        <s:complexContent mixed="false">
          <s:extension base="s1:GenericMsg">
            <s:sequence>
              <s:element minOccurs="0" maxOccurs="1" name="MessageResult" type="s:string" />
              <s:element minOccurs="0" maxOccurs="1" default="OK" name="MessageStatus" type="s1:MessageStatusType" />
              <s:element minOccurs="0" maxOccurs="1" name="MessageErrorCode" type="s:string" />
            </s:sequence>
          </s:extension>
        </s:complexContent>
      </s:complexType>
      <s:simpleType name="MessageStatusType">
        <s:restriction base="s:string">
          <s:enumeration value="OK" />
          <s:enumeration value="FailedValidation" />
          <s:enumeration value="FailedExecution" />
          <s:enumeration value="FailedAuthorization" />
          <s:enumeration value="FailedOther" />
        </s:restriction>
      </s:simpleType>
      <s:complexType name="VoidOutMsg">
        <s:complexContent mixed="false">
          <s:extension base="s1:GenericOutMsg" />
        </s:complexContent>
      </s:complexType>
      <s:complexType name="LedgerOutMsg">
        <s:complexContent mixed="false">
          <s:extension base="s1:GenericOutMsg">
            <s:sequence>
              <s:element minOccurs="1" maxOccurs="1" name="Id" type="s:int" />
            </s:sequence>
          </s:extension>
        </s:complexContent>
      </s:complexType>
      <s:complexType name="RefundOutMsg">
        <s:complexContent mixed="false">
          <s:extension base="s1:LedgerOutMsg" />
        </s:complexContent>
      </s:complexType>
      <s:complexType name="ChargeOutMsg">
        <s:complexContent mixed="false">
          <s:extension base="s1:LedgerOutMsg" />
        </s:complexContent>
      </s:complexType>
      <s:complexType name="PaymentOutMsg">
        <s:complexContent mixed="false">
          <s:extension base="s1:LedgerOutMsg" />
        </s:complexContent>
      </s:complexType>
      <s:complexType name="VoidInMsg">
        <s:complexContent mixed="false">
          <s:extension base="s1:GenericInMsg">
            <s:sequence>
              <s:element minOccurs="1" maxOccurs="1" name="StudentId" type="s:int" />
              <s:element minOccurs="1" maxOccurs="1" name="TransactionId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" name="Comment" type="s:string" />
              <s:element minOccurs="1" maxOccurs="1" name="IsNonSufficientFunds" type="s:boolean" />
              <s:element minOccurs="1" maxOccurs="1" name="IsReschedule" type="s:boolean" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="SubsidiaryId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="1900-01-01T00:00:00" name="TransactionDate" type="s:dateTime" />
              <s:element minOccurs="0" maxOccurs="1" default="1900-01-01T00:00:00" name="PostingDate" type="s:dateTime" />
            </s:sequence>
          </s:extension>
        </s:complexContent>
      </s:complexType>
      <s:complexType name="RefundInMsg">
        <s:complexContent mixed="false">
          <s:extension base="s1:LedgerInMsg">
            <s:sequence>
              <s:element minOccurs="1" maxOccurs="1" name="ScheduledRefunds" type="s:boolean" />
              <s:element minOccurs="1" maxOccurs="1" name="ReadyToSendToCOD" type="s:boolean" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="EnrollmentId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="FaHeaderId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="StudentAcademicYearId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" name="Comment" type="s:string" />
              <s:element minOccurs="0" maxOccurs="1" name="CheckNumber" type="s:string" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="BankAccountId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="StudentAddressId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="1900-01-01T00:00:00" name="DateSent" type="s:dateTime" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="RefundId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" name="ReceiptNo" type="s:string" />
              <s:element minOccurs="1" maxOccurs="1" name="IsStipend" type="s:boolean" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="CreditCardBatchId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="StipendSchedId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="StudentCreditCardId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="false" name="AllowRefundGreaterThanBalance" type="s:boolean" />
              <s:element minOccurs="0" maxOccurs="unbounded" name="DisbursementAmountMsg" type="s1:DisbursementAmountMsg" />
              <s:element minOccurs="1" maxOccurs="1" name="ReturnMethod" type="s1:ReturnMethod" />
              <s:element minOccurs="1" maxOccurs="1" name="PaymentType" type="s1:PaymentType" />
            </s:sequence>
          </s:extension>
        </s:complexContent>
      </s:complexType>
      <s:complexType name="DisbursementAmountMsg">
        <s:sequence>
          <s:element minOccurs="1" maxOccurs="1" name="DisbursementId" type="s:int" />
          <s:element minOccurs="1" maxOccurs="1" name="Amount" type="s:decimal" />
        </s:sequence>
      </s:complexType>
      <s:simpleType name="ReturnMethod">
        <s:restriction base="s:string">
          <s:enumeration value="Net" />
          <s:enumeration value="Check" />
          <s:enumeration value="MasterCheck" />
          <s:enumeration value="EFT" />
          <s:enumeration value="ACH" />
          <s:enumeration value="CreditCard" />
        </s:restriction>
      </s:simpleType>
      <s:simpleType name="PaymentType">
        <s:restriction base="s:string">
          <s:enumeration value="Cash" />
          <s:enumeration value="Check" />
          <s:enumeration value="CreditCard" />
          <s:enumeration value="EFT" />
          <s:enumeration value="NonCash" />
          <s:enumeration value="ACH" />
          <s:enumeration value="Other" />
        </s:restriction>
      </s:simpleType>
      <s:complexType name="ChargeInMsg">
        <s:complexContent mixed="false">
          <s:extension base="s1:LedgerInMsg">
            <s:sequence>
              <s:element minOccurs="1" maxOccurs="1" name="TransactionCodeId" type="s:int" />
              <s:element minOccurs="1" maxOccurs="1" name="TransactionType" type="s1:TransactionType" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="StudentAcademicYearId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="EnrollmentId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="false" name="UpdateEnrollmentDateBilled" type="s:boolean" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="PaymentPeriodId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="CourseSectionId" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" default="-1" name="FeeId" type="s:int" />
              <s:element minOccurs="1" maxOccurs="1" name="Offset" nillable="true" type="s:int" />
            </s:sequence>
          </s:extension>
        </s:complexContent>
      </s:complexType>
      <s:simpleType name="TransactionType">
        <s:restriction base="s:string">
          <s:enumeration value="Invoice" />
          <s:enumeration value="DebitMemo" />
          <s:enumeration value="CreditMemo" />
          <s:enumeration value="Payment" />
        </s:restriction>
      </s:simpleType>
      <s:simpleType name="AwardYearType">
        <s:restriction base="s:string">
          <s:enumeration value="None" />
          <s:enumeration value="AY2020_21" />
          <s:enumeration value="AY2021_22" />
          <s:enumeration value="AY2022_23" />
          <s:enumeration value="AY2023_24" />
          <s:enumeration value="AY2024_25" />
          <s:enumeration value="AY2025_26" />
        </s:restriction>
      </s:simpleType>
      <s:complexType name="PaymentDistributionMsg">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="BillCode" type="s:string" />
          <s:element minOccurs="1" maxOccurs="1" name="AmountApplied" type="s:decimal" />
        </s:sequence>
      </s:complexType>
      <s:complexType name="ArrayOfChargeInMsg">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="unbounded" name="ChargeInMsg" nillable="true" type="s1:ChargeInMsg" />
        </s:sequence>
      </s:complexType>
      <s:complexType name="ArrayOfRefundInMsg">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="unbounded" name="RefundInMsg" nillable="true" type="s1:RefundInMsg" />
        </s:sequence>
      </s:complexType>
      <s:complexType name="ArrayOfVoidInMsg">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="unbounded" name="VoidInMsg" nillable="true" type="s1:VoidInMsg" />
        </s:sequence>
      </s:complexType>
      <s:element name="PostLedgerResponse" type="s1:PostLedgerResponse" />
      <s:complexType name="PostLedgerResponse">
        <s:complexContent mixed="false">
          <s:extension base="s1:GenericResponse">
            <s:sequence>
              <s:element minOccurs="0" maxOccurs="1" name="Payments" type="s1:ArrayOfPaymentOutMsg" />
              <s:element minOccurs="0" maxOccurs="1" name="Charges" type="s1:ArrayOfChargeOutMsg" />
              <s:element minOccurs="0" maxOccurs="1" name="Refunds" type="s1:ArrayOfRefundOutMsg" />
              <s:element minOccurs="0" maxOccurs="1" name="Voids" type="s1:ArrayOfVoidOutMsg" />
            </s:sequence>
          </s:extension>
        </s:complexContent>
      </s:complexType>
      <s:complexType name="GenericResponse">
        <s:sequence>
          <s:element minOccurs="1" maxOccurs="1" name="Status" type="s1:TrxStatus" />
          <s:element minOccurs="0" maxOccurs="1" name="TrxResult" type="s:string" />
          <s:element minOccurs="0" maxOccurs="1" name="TokenId" type="s:string" />
        </s:sequence>
      </s:complexType>
      <s:simpleType name="TrxStatus">
        <s:restriction base="s:string">
          <s:enumeration value="OK" />
          <s:enumeration value="ErrorSQL" />
          <s:enumeration value="ErrorBusinessLogic" />
          <s:enumeration value="ErrorWebService" />
          <s:enumeration value="ErrorArguments" />
          <s:enumeration value="ErrorSecurity" />
          <s:enumeration value="ErrorSystem" />
          <s:enumeration value="ErrorMultiple" />
        </s:restriction>
      </s:simpleType>
      <s:complexType name="ArrayOfPaymentOutMsg">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="unbounded" name="PaymentOutMsg" nillable="true" type="s1:PaymentOutMsg" />
        </s:sequence>
      </s:complexType>
      <s:complexType name="ArrayOfChargeOutMsg">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="unbounded" name="ChargeOutMsg" nillable="true" type="s1:ChargeOutMsg" />
        </s:sequence>
      </s:complexType>
      <s:complexType name="ArrayOfRefundOutMsg">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="unbounded" name="RefundOutMsg" nillable="true" type="s1:RefundOutMsg" />
        </s:sequence>
      </s:complexType>
      <s:complexType name="ArrayOfVoidOutMsg">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="unbounded" name="VoidOutMsg" nillable="true" type="s1:VoidOutMsg" />
        </s:sequence>
      </s:complexType>
    </s:schema>
  </wsdl:types>
  <wsdl:message name="PostLedgerSoapIn">
    <wsdl:part name="parameters" element="tns:PostLedger" />
  </wsdl:message>
  <wsdl:message name="PostLedgerSoapOut">
    <wsdl:part name="parameters" element="tns:PostLedgerResponse" />
  </wsdl:message>
  <wsdl:message name="PostLedgerRequestHeader">
    <wsdl:part name="RequestHeader" element="tns:RequestHeader" />
  </wsdl:message>
  <wsdl:message name="PostLedgerResponseHeader">
    <wsdl:part name="ResponseHeader" element="tns:ResponseHeader" />
  </wsdl:message>
  <wsdl:portType name="LedgerWebServiceSoap">
    <wsdl:operation name="PostLedger">
      <wsdl:input message="tns:PostLedgerSoapIn" />
      <wsdl:output message="tns:PostLedgerSoapOut" />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="LedgerWebServiceSoap" type="tns:LedgerWebServiceSoap">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="PostLedger">
      <soap:operation soapAction="http://www.example.com/Soa/Foundation/PostLedger" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
        <soap:header message="tns:PostLedgerRequestHeader" part="RequestHeader" use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
        <soap:header message="tns:PostLedgerResponseHeader" part="ResponseHeader" use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:binding name="LedgerWebServiceSoap12" type="tns:LedgerWebServiceSoap">
    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="PostLedger">
      <soap12:operation soapAction="http://www.example.com/Soa/Foundation/PostLedger" style="document" />
      <wsdl:input>
        <soap12:body use="literal" />
        <soap12:header message="tns:PostLedgerRequestHeader" part="RequestHeader" use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap12:body use="literal" />
        <soap12:header message="tns:PostLedgerResponseHeader" part="ResponseHeader" use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="LedgerWebService">
    <wsdl:port name="LedgerWebServiceSoap" binding="tns:LedgerWebServiceSoap">
      <soap:address location="https://api.example.com/webservices/LedgerWebService.asmx" />
    </wsdl:port>
    <wsdl:port name="LedgerWebServiceSoap12" binding="tns:LedgerWebServiceSoap12">
      <soap12:address location="https://api.example.com/webservices/LedgerWebService.asmx" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
"""

def test_missing_array():
    """
    suds-community gives this:
    -----
    (PostLedgerRequest){
       TokenId = None
       Payments = None
       Charges = None
       Refunds = None
       Voids = None
    }

    versus suds-jurko:
    ----
    (PostLedgerRequest){
       TokenId = None
       Payments =
          (ArrayOfPaymentInMsg){
             PaymentInMsg[] = <empty>
          }
       Charges =
          (ArrayOfChargeInMsg){
             ChargeInMsg[] = <empty>
          }
       Refunds =
          (ArrayOfRefundInMsg){
             RefundInMsg[] = <empty>
          }
       Voids =
          (ArrayOfVoidInMsg){
             VoidInMsg[] = <empty>
          }
    }

    All of this seems to be caused by github issues #14, #15, and #16
    https://github.com/suds-community/suds/pull/16
    """
    wsdl = suds.byte_str(ledger_wsdl)
    client = testutils.client_from_wsdl(wsdl)
    # print(client)
    assert client is not None
    req = client.factory.create("ns1:PostLedgerRequest")
    print(req)
    for a in ["Payments", "Charges", "Refunds", "Voids"]:
        assert hasattr(req, a)
        assert getattr(req, a) is not None
    assert req.Payments.__class__.__name__ == "ArrayOfPaymentInMsg"
    assert req.Charges.__class__.__name__ == "ArrayOfChargeInMsg"
    assert req.Refunds.__class__.__name__ == "ArrayOfRefundInMsg"
    assert req.Voids.__class__.__name__ == "ArrayOfVoidInMsg"

    print(req.Payments)
    print(req.Payments.PaymentInMsg)
    assert isinstance(req.Payments.PaymentInMsg, list)

    # Try setting the value
    sample_charge = client.factory.create("ns1:ChargeInMsg")
    # ... We would populate all of sample_charge here
    sample_charge.StudentId = 1234
    sample_charge.Description = "Room and Board"
    sample_charge.Amount = 987.65
    # Add to the request
    req.Charges.ChargeInMsg = [sample_charge,]
    # if req.Charges is None, cannot do above, but
    # the following doesn't seem to work correctly
    # req.Charges = [sample_charge,]
    print(req)
    assert req.Charges.ChargeInMsg
    print(req.Charges.ChargeInMsg[0])
    assert req.Charges.ChargeInMsg[0] == sample_charge

Question about expected schema behavior and prefixes

I have a WSDL that imports a schema. The WSDL contains the prefix for the namespace, and the schema contains the type information for the parameters of a method, but Suds will not prefix the parameter's XML element until I add that prefix and namespace to the schema itself. I didn't write the WSDL and schema so it's entirely possible they just wrote it wrong. However, I've seen quite a few different WSDL + schema examples that don't do this, so I'm unsure what the standard practice is.

In short, is it standard practice to require both the WSDL and any imported schemas to define the prefix for a namespace?

WSDL definitions - tmdd is the prefix in question

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.tmdd.org/303/dialogs" xmlns:tmdd="http://www.tmdd.org/303/messages" name="TMDDCenterServices" targetNamespace="http://www.tmdd.org/303/dialogs">

Schema definition in xsd

<xs:schema xmlns="http://www.tmdd.org/303/messages" targetNamespace="http://www.tmdd.org/303/messages" elementFormDefault="unqualified" attributeFormDefault="unqualified" version="DRAFT">

Produces request with the ns, not the prefix. centerActiveVerificationRequestMsg is the parameter in question

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.tmdd.org/303/messages"><SOAP-ENV:Header/>
<ns0:Body>
<centerActiveVerificationRequestMsg xmlns="http://www.tmdd.org/303/messages">
<authentication/>
<organization-requesting>
<organization-id>1</organization-id>
</organization-requesting>
</centerActiveVerificationRequestMsg>
</ns0:Body>
</SOAP-ENV:Envelope>

If I add the tmdd prefix to the schema definition, like so (or any prefix with that url, apparently)

<xs:schema xmlns="http://www.tmdd.org/303/messages" xmlns:tmdd="http://www.tmdd.org/303/messages" targetNamespace="http://www.tmdd.org/303/messages" elementFormDefault="unqualified" attributeFormDefault="unqualified" version="DRAFT">

It then does produce the request with the prefix for the parameter centerActiveVerificationRequestMsg instead of the ns

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.tmdd.org/303/messages"><SOAP-ENV:Header/>
<ns0:Body>
<ns1:centerActiveVerificationRequestMsg>
<authentication/><organization-requesting>
<organization-id>1</organization-id>
</organization-requesting>
</ns1:centerActiveVerificationRequestMsg>
</ns0:Body>
</SOAP-ENV:Envelope>

Relevant part of WSDL. tmdd is the prefix for the attributes in question

...
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.tmdd.org/303/dialogs" xmlns:tmdd="http://www.tmdd.org/303/messages" name="TMDDCenterServices" targetNamespace="http://www.tmdd.org/303/dialogs">
...
<types>
	<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
		<xs:import namespace="http://www.tmdd.org/303/messages" schemaLocation="TMDD.xsd"/>
	</xs:schema>
</types>
...
<message name="MSG_CenterActiveVerificationRequest">
	<part name="message" element="tmdd:centerActiveVerificationRequestMsg"/>
</message>
...
<portType "tmddOCSoapHttpServicePortType">
...
        <operation name="dlCenterActiveVerificationRequest">
	        <documentation><objectClass>ConnectionManagement</objectClass><objectClass>ExternalCenter</objectClass><objectClass>OwnerCenter</objectClass><msgPattern>R-R</msgPattern><requirement>REQ199</requirement></documentation>
		<input message="tns:MSG_CenterActiveVerificationRequest"/>
		<output message="tns:MSG_CenterActiveVerificationResponse"/>
		<fault name="errorReport" message="tns:MSG_ErrorReport"/>
	</operation>
...
</portType>
<binding name="tmddOCSoapHttpServiceBinding" type="tns:tmddOCSoapHttpServicePortType">
...
<operation name="dlCenterActiveVerificationRequest">
	<soap:operation soapAction="''" style="document"/>
	<input>
		<soap:body use="literal"/>
	</input>
	<output>
		<soap:body use="literal"/>
	</output>
	<fault name="errorReport">
		<soap:fault name="errorReport" use="literal"/>
	</fault>
</operation>
...
</binding>

Relevant part of Schema

...
<xs:schema xmlns="http://www.tmdd.org/303/messages" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ntcip="http://www.ntcip.org/c2f-object-references" xmlns:c2c="http://www.ntcip.org/c2c-message-administration" xmlns:itis="http://www.ITIS-Adopted-03-00-02" xmlns:lrms="http://www.LRMS-Adopted-02-00-00" targetNamespace="http://www.tmdd.org/303/messages" elementFormDefault="unqualified" attributeFormDefault="unqualified" version="DRAFT">
...
	<xs:element name="centerActiveVerificationRequestMsg" type="CenterActiveVerificationRequest">
		<xs:annotation>
			<xs:documentation>
				<objectClass>ConnectionManagement</objectClass>
				<requirement>REQ1125</requirement>
			</xs:documentation>
		</xs:annotation>
	</xs:element>
...
<xs:complexType name="CenterActiveVerificationRequest">
		<xs:annotation>
			<xs:documentation>
				<objectClass>ConnectionManagement</objectClass>
			</xs:documentation>
		</xs:annotation>
		<xs:sequence>
			<xs:element name="authentication" type="Authentication">
				<xs:annotation>
					<xs:documentation>
						<requirement>REQ201</requirement>
					</xs:documentation>
				</xs:annotation>
			</xs:element>
			<xs:element name="organization-requesting" type="OrganizationInformation">
				<xs:annotation>
					<xs:documentation>
						<requirement>REQ201</requirement>
					</xs:documentation>
				</xs:annotation>
			</xs:element>
			<xs:any namespace="##other" processContents="lax" minOccurs="0"/>
		</xs:sequence>
	</xs:complexType>
...

WSDL: https://scos-third-party-repository.s3.us-east-2.amazonaws.com/wsdl/tmdd_local.wsdl
Schema: https://scos-third-party-repository.s3.us-east-2.amazonaws.com/wsdl/TMDD.xsd

consider moving suds-community to jazzband

From the website (https://jazzband.co/):

Jazzband is a collaborative community to share the responsibility of maintaining Python-based projects.

It gives maintainers and contributors the ability to “play in the same band” instead of being forced into “artist” and “audience” roles.

When you join Jazzband you will become a member of its GitHub organization and granted a wide range of privileges there such as pushing code to repositories, triaging issues, merging pull requests, etc.

You can leave administrative tasks to the roadies, the people making sure the band can play when they want.
Once you are a member you can transfer an existing repo to the Jazzband organization as long as you follow the guidelines. There are also many existing Jazzband projects which you can start contributing directly.

When creating a new project or moving an existing one to the Jazzband there are some guidelines to follow. They exist to make sure that the Jazzband stays useful as a place to share responsibility for software maintenance when a number of projects are created at or moved to it.

Checklist:

  • Visibility: Established projects with a history of outside contributions that seek more maintainers are best suited for transfer to the Jazzband.
  • Documentation: Projects require prose documentation for end users and contributors. Inline code documentation is considered an indicator for a high quality of code and is also strongly recommended.
  • Tests: Projects must have tests that are easy to run. Automatic testing based on contributions (e.g. GitHub Actions) is also strongly encouraged. The test coverage requirement follows the “perfect is the enemy of the good” motto – it’s enough if the tests cover the core API of the project.
  • Conduct: Projects are required to adopt and follow the Jazzband code of conduct. Please see the Contributor Code of Conduct for more information what that entails and how to report conduct violations.
  • Contributing Guidelines: Projects have to add a CONTRIBUTING.md or CONTRIBUTING.rst file to their repository so it’s automatically displayed when new issues and pull requests are created.

Zeep and other forks

gzip and deflate compression with headers 'Content-Encoding' and 'Accept-Encoding'

Suds library does not take into account headers like 'Content-Encoding' and 'Accept-Encoding'

The following patch fixes the bug.

sebromon@ad12bc4

With this commit :

  • Message is compressed if Content-Encoding is provided and equals to gzip or deflate.
  • Message is decompressed if Content-Encoding is present in response headers and equals to gzip or deflate.

But suds library should use urllib3 which compress or decompress data automatically.

This patch works in Python 3 with web-services SOAP with Apache server.

Remove star imports

There are many star imports in the code, we should work to remove them because:

  • it pollutes the namespace and may shadow other objects (from previous imports)
  • it's poor readability/debugging -it's not clear what's imported where
  • much static analysis is not available (either typing or other linting)

This is a relatively straight forward change to make (e.g. can use https://www.asmeurer.com/removestar/), but it has the potential for being a "breaking change" for imports from suds. Since many modules do from suds import *, this has the potential to mean that prior imports like from suds.builder import Webfault will no longer work.

These internal imports are not documented, so in theory are not part of the public API. Python itself treats this as a non breaking change: https://docs.python.org/3/whatsnew/3.7.html#changes-in-the-python-api

Several undocumented internal imports were removed. One example is that os.errno is no longer available; use import errno directly instead. Note that such undocumented internal imports may be removed any time without notice, even in micro version releases.

AttributeError: 'NoneType' object has no attribute 'promotePrefixes'

Getting the error when using suds in python 2.7

My code looks like this -

from suds.client import Client
import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)

client = Client("http://...?wsdl")

a1 = client.factory.create('A1Type')
a1.attribute1="a11value"
a1.attribute2="a12value"

client.set_options(soapheaders=a1)
client.set_options(location="http://...")

p1 = client.factory.create('P1Type')
p1.attribute1="p11value"
p1.attribute2="p12value"

resp=client.service.method(p1)


Traceback (most recent call last):
File "C:\someDirectory\C0\pylib\site-packages\suds\client.py", line 542, in call
return client.invoke(args, kwargs)
File "C:\someDirectory\C0\pylib\site-packages\suds\client.py", line 602, in invoke
result = self.send(soapenv)
File "C:\someDirectory\C0\pylib\site-packages\suds\client.py", line 643, in send
result = self.succeeded(binding, reply.message)
File "C:\someDirectory\C0\pylib\site-packages\suds\client.py", line 643, in send
result = self.succeeded(binding, reply.message)
File "C:\someDirectory\C0\pylib\site-packages\suds\client.py", line 678, in succeeded
reply, result = binding.get_reply(self.method, reply)
File "C:\someDirectory\C0\pylib\site-packages\suds\bindings\binding.py", line 149, in get_reply
soapenv.promotePrefixes()
AttributeError: 'NoneType' object has no attribute 'promotePrefixes'

It seems like the whole wsdl is being returned. Soap webservice works in SOAP-UI with same XML soap request.

Allow setting timeout per endpoint (or per call)

Currently a timeout can be set per client so that it is enforced globally for the client. However, if a specific endpoint is slow and a service wants to enforce a different timeout per endpoint, that is not (easily) possible.

Each service call does the following:

reply = self.options.transport.send(request)

fp = self.u2open(u2request)

return url.open(u2request, timeout=tm)

Currently all invocations of calls accept a __inject parameter: https://github.com/suds-community/suds#message-injection--diagnosticstesting

client factory return <empty>

good morning,

I was making a soap client with suds while running the factory like this:

domicilio = client.factory.create('ns0:Domicilio')
(Domicilio){
   indirizzo = None
   tipoAbitazione = None
   annoInizioAbitazione = None
   costoAbitazione = None
 }

.....is OK

if I try another one:

venditore = client.factory.create('ns0:VenditoreId')

this is the return:

" empty"

the xml that define ns0:VenditoreId is:

<xsd:complexType name="VenditoreId">
                                <xsd:sequence>
                                        <xsd:element maxOccurs="1" minOccurs="1" name="codice" type="xsd:string">
                                                <xsd:annotation>
                                                        <xsd:documentation>
                                                                xxxx some description
                                                        </xsd:documentation>
                                                </xsd:annotation>
                                        </xsd:element>
                                </xsd:sequence>
                        </xsd:complexType>

Better debug log output...

I have made a simple log handler for 'suds.transport' that will print the binary output a little bit better to the console.

The normal output:

grafik

With this hacked handler:

grafik

The source code is here: django-oscar/django-oscar-docdata#33

But it's a better place to include this into the suds project, isn't it?

Any interest here? Then I would try to make an pull request.

ConnectionResetError: [Errno 104] Connection reset by peer

It was working fine till yesterday.
Nothing changed. same network, same code but no solution till now. Any help would be highly appreciated

Traceback (most recent call last):
  File "/opt/wwts/opt/dashboard/dashboard/wmp_sockets.py", line 5, in <module>
    from dashboard import app
  File "/opt/wwts/opt/dashboard/dashboard/__init__.py", line 73, in <module>
    from .work_order.views import blueprint as work_order_views  # noqa
  File "/opt/wwts/opt/dashboard/dashboard/work_order/views.py", line 96, in <module>
    from dashboard.work_order.service import CallCertificationsService
  File "/opt/wwts/opt/dashboard/dashboard/work_order/service.py", line 17, in <module>
    _gtcd = GTCallData()
  File "/opt/wwts/opt/dashboard/dashboard/wwits_apis/soap.py", line 159, in __init__
    super(WwitsClient, self).__init__(
  File "/opt/wwts/lib/python3.8/site-packages/suds/client.py", line 120, in __init__
    self.wsdl = reader.open(url)
  File "/opt/wwts/lib/python3.8/site-packages/suds/reader.py", line 104, in open
    wsdl = self.fn(url, self.options)
  File "/opt/wwts/lib/python3.8/site-packages/suds/wsdl.py", line 190, in __init__
    self.build_schema()
  File "/opt/wwts/lib/python3.8/site-packages/suds/wsdl.py", line 252, in build_schema
    self.schema = container.load(self.options, loaded_schemata)
  File "/opt/wwts/lib/python3.8/site-packages/suds/xsd/schema.py", line 102, in load
    child.open_imports(options, loaded_schemata)
  File "/opt/wwts/lib/python3.8/site-packages/suds/xsd/schema.py", line 351, in open_imports
    imported = imp.open(options, loaded_schemata)
  File "/opt/wwts/lib/python3.8/site-packages/suds/xsd/sxbasic.py", line 578, in open
    self.__download(url, loaded_schemata, options))
  File "/opt/wwts/lib/python3.8/site-packages/suds/xsd/sxbasic.py", line 591, in __download
    d = reader.open(url)
  File "/opt/wwts/lib/python3.8/site-packages/suds/reader.py", line 148, in open
    xml = self.__fetch(url)
  File "/opt/wwts/lib/python3.8/site-packages/suds/reader.py", line 189, in __fetch
    fp = self.options.transport.open(request)
  File "/opt/wwts/lib/python3.8/site-packages/suds/transport/https.py", line 62, in open
    return HttpTransport.open(self, request)
  File "/opt/wwts/lib/python3.8/site-packages/suds/transport/http.py", line 67, in open
    return self.u2open(u2request)
  File "/opt/wwts/lib/python3.8/site-packages/suds/transport/http.py", line 128, in u2open
    return url.open(u2request, timeout=tm)
  File "/opt/wwts/lib/python3.8/urllib/request.py", line 525, in open
    response = self._open(req, data)
  File "/opt/wwts/lib/python3.8/urllib/request.py", line 542, in _open
    result = self._call_chain(self.handle_open, protocol, protocol +
  File "/opt/wwts/lib/python3.8/urllib/request.py", line 502, in _call_chain
    result = func(*args)
  File "/opt/wwts/lib/python3.8/urllib/request.py", line 1379, in http_open
    return self.do_open(http.client.HTTPConnection, req)
  File "/opt/wwts/lib/python3.8/urllib/request.py", line 1354, in do_open
    r = h.getresponse()
  File "/opt/wwts/lib/python3.8/http/client.py", line 1347, in getresponse
    response.begin()
  File "/opt/wwts/lib/python3.8/http/client.py", line 307, in begin
    version, status, reason = self._read_status()
  File "/opt/wwts/lib/python3.8/http/client.py", line 268, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "/opt/wwts/lib/python3.8/socket.py", line 669, in readinto
    return self._sock.recv_into(b)

README improvements / clarification

Just some ideas:

  • The descriptions says "A community fork of the jurko fork.". I can not see that this info is part of the README. IMHO I think you need to repeat it since the README should be self contained.
  • Make it clear which Python versions are supported or at least which versions you try to support.
  • Split the README in two files - a shorter README file with installation instructions and made an Hello World example and a longer USAGE file or DOCUMENTATION file with the rest of the info.
  • I assume the sentence "This is hopefully just a temporary fork of the original suds Python library project created because the original project development seems to have stalled. Should be reintegrated back into the original project if it ever gets revived again." is coming from the jurko fork? However, the Fedora hosted version will never come back. And it might be read as you want this project reintegrated in the jurko fork. Maybe just delete it?

Thx for reading this far. If none of the above make sense to you, just close the issue.

Async requests

Can N requests be queued and sent asynchronously? Haven't found any references in the documentation. Best alternative?

Suds vs SoapClient

Hi, I'm having different results while creating a soap client and a suds client.

I don't understand a lot about soap, but I think both so should be the same right?

Clean up epydocs formatting

Most of the codebase is formatted to use epydocs-style docs for functions and classes. This is largely translated to sphinx style formatting for the readthedocs doc generation process at generation time time here:

suds/docs/source/conf.py

Lines 28 to 29 in 6117f17

# Convert from epydocs to Sphinx style docstrings
os.system('../migrate_docstrings.sh ../../suds/')

We should commit these changes to code as a permanent change.

Create suds-community conda package on conda-forge

I was very glad to discover suds-community, after using suds-jurko (and suds before that) for a few years and realizing that it's no longer maintained.

There's been a suds-jurko conda package on conda-forge for a long time, and it'd be great to have a suds-community package there as well. I can offer to help with this.

It's fairly easy to do this. See the Getting started section of the conda-forge/staged-recipes README file, possibly supplemented by the Step-by-step Instructions here. To generate the content of the conda recipe meta.yml file, I recommend the Grayskull online tool, which only needs the name of the pip package (it runs successfully with suds-community); you then only need to edit it by replacing ADD_YOUR_GITHUB_ID_HERE with the maintainer's github handle.

Add custom cache

Hi!

I see that Client has an option to cache the wsdls, but I think it would be useful to let users handle the caching.

The way I picture it, is to pass an URL pointing to a file containing the wsdl instead of a web URL, so the Client doesn't have to download it as it is already provided.

Thanks!

Is suds-community currently compatible with suds-jurko?

Sorry if this can be found somewhere else, but I can't find it, I have a current setup working with suds-jurko, I would like to migrate it to a maintained fork. I have this code that has been working for a couple of years:

from suds import client
from suds.sudsobject import asdict
from suds import WebFault

But now I get an error when importing the class.

    from suds import client
ImportError: cannot import name 'client' from 'suds' (unknown location) 

Issue might be very basic but I haven't been able to fix it, also I was thinking that remove suds-jurko and adding instead suds-community would do the job.

How to pass XML string to SOAP call using Suds for Python3

Using suds-py3.

When loading the following WSDL:

https://clientdev.inteflow.com.au/inteport/DecisionGateway.asmx?WSDL

I get:

(DecisionWebGatewaySoap12)
         Methods (38):
            [...]
            ExecuteXMLRequest(_sRequestXML _sRequestXML, )

The types list contains all this, but nothing called _sRequestXML (which should be treated as a string, I reckon):

   Types (141):
      AccessGroup
      Address
      ns3:AddressInformation
      Applicant
      ns2:Array
      ArrayOfAccessGroup
      ArrayOfApplicant
      ns3:ArrayOfAttachment
      ArrayOfCriteria
      ns3:ArrayOfCustomField
      ns3:ArrayOfDocumentPDF
      ns3:ArrayOfDocumentStatus
      ns3:ArrayOfFormDataXfdfField
      ArrayOfMerchantCommission
      ArrayOfMerchantOperator
      ArrayOfMerchantParameter
      ArrayOfMerchantProductGroup
      ArrayOfMerchantProductv2
      ArrayOfOperatorAccessGroup
      ArrayOfOperatorMerchant
      ArrayOfOperatorProductGroup
      ns3:ArrayOfRecipientStatus
      ArrayOfString
      ns3:ArrayOfString
      ns3:ArrayOfTabStatus
      ArrayOfURL
      ns3:Attachment
      Authentication
      ns3:AuthenticationStatus
      BasicInsuranceProduct
      BasicMerchant
      BasicMerchantOperator
      BasicOperator
      CompanyDetails
      Contact
      CreateInsuranceProductResponseData
      CreateMerchantResponseData
      Criteria
      ns3:CustomField
      ns3:CustomFieldType
      ns3:CustomTabType
      ns3:DOBInformation
      DateFormat
      DefaultValue
      ns3:DeliveryMethod
      ns3:DocuSignEnvelopeInformation
      ns3:DocumentPDF
      ns3:DocumentStatus
      ns3:DocumentType
      ns2:ENTITIES
      ns2:ENTITY
      ns3:EnvelopeStatus
      ns3:EnvelopeStatusCode
      ns3:EventResult
      ns3:EventStatusCode
      ExecuteResponse
      FinanceRequest
      Financial
      ns3:FormData
      ns3:FormDataXfdf
      ns3:FormDataXfdfField
      ns2:ID
      ns3:IDCheckInformation
      ns2:IDREF
      ns2:IDREFS
      IndividualDetails
      LimitedLoginResponseData
      Merchant
      MerchantCommission
      MerchantDetails
      MerchantOperator
      MerchantParameter
      MerchantProductGroup
      MerchantProductv2
      ns2:NCName
      ns2:NMTOKEN
      ns2:NMTOKENS
      ns2:NOTATION
      ns2:Name
      Operator
      OperatorAccessGroup
      OperatorDetails
      OperatorFlag
      OperatorMerchant
      OperatorProductGroup
      Options
      Payload
      PayloadSubmit
      ns2:QName
      ns3:RecipientStatus
      ns3:RecipientStatusCode
      ns3:RecipientStatusEsignAgreementInformation
      ns3:RecipientTypeCode
      RequestData
      RequestResponseData
      ResponseData
      ns3:SSN4Information
      SecondaryLogin
      ns3:SigningLocationCode
      StatusCheck
      ns1:StringArray
      ns2:Struct
      ns3:TabStatus
      ns3:TabTypeCode
      URL
      ns3:VaultingDetails
      ns2:anyURI
      ns2:arrayCoordinate
      ns2:base64
      ns2:base64Binary
      ns2:boolean
      ns2:byte
      ns2:date
      ns2:dateTime
      ns2:decimal
      ns2:double
      ns2:duration
      ns2:float
      ns2:gDay
      ns2:gMonth
      ns2:gMonthDay
      ns2:gYear
      ns2:gYearMonth
      ns2:hexBinary
      ns2:int
      ns2:integer
      ns2:language
      ns2:long
      ns2:negativeInteger
      ns2:nonNegativeInteger
      ns2:nonPositiveInteger
      ns2:normalizedString
      ns2:positiveInteger
      ns2:short
      ns2:string
      ns2:time
      ns2:token
      ns2:unsignedByte
      ns2:unsignedInt
      ns2:unsignedLong
      ns2:unsignedShort

Then, when I do:

v = client.service.ExecuteXMLRequest("<inteflow><something>value</something></inteflow>")

The SOAP string I passed to ExecuteXMLRequest is not set as the value of ns1:ExecuteXMLRequest. Instead, the element is empty:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://decisionintellect.com/inteport/">
   <SOAP-ENV:Header/>
   <ns0:Body>
      <ns1:ExecuteXMLRequest/>
   </ns0:Body>
</SOAP-ENV:Envelope>

I need Suds to produce an envelope like this instead:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://decisionintellect.com/inteport/">
   <SOAP-ENV:Header/>
   <ns0:Body>
      <ns1:ExecuteXMLRequest>
            <ns1:_sRequestXML>
                  <inteflow><something>value</something></inteflow>
            </ns1:_sRequestXML>
      </ns1:ExecuteXMLRequest>
   </ns0:Body>
</SOAP-ENV:Envelope>

Is there a problem with the WSDL?
Should I pass the parameter in some other way?

Full example:

import ssl

from suds.client import Client

if hasattr(ssl, '_create_unverified_context'):
    ssl._create_default_https_context = ssl._create_unverified_context

url = 'https://clientdev.inteflow.com.au/inteport/DecisionGateway.asmx?WSDL'
client = Client(url)
client.set_options(port='DecisionWebGatewaySoap12')

print(client)

v = client.service.ExecuteXMLRequest("<inteflow><something>value</something></inteflow>")
print(client.last_sent())

print(v)

nonempty __slots__ not supported for subtype of 'str' TypeError: Error when calling the metaclass bases

Hi guys, I know it's a pain ... I already see #68 :(
After a while of poking around on the net, I found out that this is a very old discussion. Since none of the tips I found have worked for me, I'm leaving the question here to see if anyone can throw me a line of help.

pip2 install suds
Downloading/unpacking suds
Downloading suds-1.0.0.tar.gz (283kB): 283kB downloaded

my code is silly simple and runs smoothly from a python 2.7.9 prompt:

from suds.client import Client
client = Client(ws_url)

res = client.service.remote_method(...)

The error comes when you call the function where this code live.

    from suds.sax.text import Text
  File "/usr/local/lib/python2.7/dist-packages/suds/sax/text.py", line 25, in <module>
    class Text(str):
TypeError: Error when calling the metaclass bases
    nonempty __slots__ not supported for subtype of 'str'

It is a legacy erp application that I cannot upgrade to py3.
Thanks you guys in advance.
Marcelo

Getting error msg while importing - 'from suds.client import Client' on Python 2.6

from suds.client import Client
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib64/python2.6/site-packages/suds/client.py", line 23, in
import suds.bindings.binding
File "/usr/local/lib64/python2.6/site-packages/suds/bindings/binding.py", line 23, in
from suds.sax.document import Document
File "/usr/local/lib64/python2.6/site-packages/suds/sax/document.py", line 23, in
from suds.sax.element import Element
File "/usr/local/lib64/python2.6/site-packages/suds/sax/element.py", line 23, in
from suds.sax.text import Text
File "/usr/local/lib64/python2.6/site-packages/suds/sax/text.py", line 25, in
class Text(str):
TypeError: Error when calling the metaclass bases
nonempty slots not supported for subtype of 'str'

suds build error: missing attribute (multi_occurance)

I encountered this in the traceback:

_*_/bingads/service_client.py", line 38, in process
if type.multi_occurrence():
AttributeError: 'Element' object has no attribute 'multi_occurrence'

It concluded with:

An error occured while building a instance of (DynamicSearchAdsSetting).  As a result
        the object you requested could not be constructed.  It is recommended
        that you construct the type manually using a Suds object.
        Please open a ticket with a description of this error.
        Reason: 'Element' object has no attribute 'multi_occurrence'

Is this something that can be fixed? Or is it a flawed dependency on my end?

For reference, here is a quick glance at the process method where it breaks:

def process(self, data, type, history):
 29         """ process the specified type then process its children """
 30         if type in history:
 31             return
 32         if type.enum():
 33             return
 34         history.append(type)
 35         resolved = type.resolve()
 36         value = None
 37 
 38         if type.multi_occurrence():
 39             value = []
 40         else:
 41             if len(resolved) > 0:
 42                 if resolved.mixed():
 43                     value = SFactory.property(resolved.name)
 44                     md = value.__metadata__
 45                     md.sxtype = resolved
 46                 else:
 47                     value = SFactory.object(resolved.name)
 48                     md = value.__metadata__
 49                     md.sxtype = resolved
 50                     md.ordering = self.ordering(resolved)
 51 
 52         setattr(data, type.name, value)
 53         if value is not None:
 54             data = value
 55         if not isinstance(data, list):
 56             self.add_attributes(data, resolved)
 57             for child, ancestry in resolved.children():
 58                 if self.skip_child(child, ancestry):
 59                     continue
 60                 self.process(data, child, history[:])

Setuptools 58.0.0 has removed support for 2to3 during builds, breaks suds for Python 3.x

More information here on the change is in the GitHub issue pypa/setuptools#2086 and in the setuptools ChangeLog https://setuptools.readthedocs.io/en/latest/history.html#v58-0-0

We now get

>>> import suds
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.7/dist-packages/suds/__init__.py", line 28, in <module>
    from version import __build__, __version__
ModuleNotFoundError: No module named 'version'

Allow backward compatible version updates via unknown message parts

Currently, if a message element is not defined in the schema, an exception is raised of the form <element> not mapped to message part, coming from:

message = "<%s/> not mapped to message part" % (tag,)
raise Exception(message)

A modest proposal

It seems like this exception could be optionally not raised via a new configuration option so that unknown elements were simply excluded from the built response structure. These unknown elements could also be logged so that there's some record of something wonky going on.

I'd be interested to see how other libraries handle this, but from some anecdotal experiences, it seems like suds is unusually in strictly enforcing this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.