0

I'm having trouble with suds.

I'm trying to make a generic system to make calls to an API, some parameters are defined as classes with multiple attributes. Initially all these attributes are empty, and I'm trying to pass a dictionary to fill some of the attributes automatically

For example:

from suds.client import Client

client = Client("...")
method = "getCampaignsByCriteria"
arg_repr = {"ids": [123]}
arg = client.factory.create("CampaignSearchCriteria")
for k, v in arg_repr.iteritems():
    setattr(arg, k, v)
service = client.service
args_map = {"searchCriteria": arg}
getattr(service, method)(**args_map)

Generates the following, with all default fields from CampaignSearchCriteria still there, and ids set correctly:

<SOAP-ENV:Body>
  <ns1:getCampaignsByCriteria>
     <searchCriteria xsi:type="ns1:CampaignSearchCriteria">
        <ids xsi:type="ns1:ArrayOf_xsd_long">123</ids>
        <searchString xsi:type="ns0:string"/>
        <pageNumber xsi:type="ns2:int"/>
        <pageSize xsi:type="ns2:int"/>
        <advertiserIds xsi:type="ns1:ArrayOf_xsd_long"/>
        <archiveFilter xsi:type="ns1:ActiveFilter">
           <activeOnly xsi:type="ns2:boolean"/>
           <inactiveOnly xsi:type="ns2:boolean"/>
        </archiveFilter>
        <sortOrder xsi:type="ns1:SortOrder">
           <descending xsi:type="ns2:boolean"/>
           <fieldName xsi:type="ns0:string"/>
        </sortOrder>
     </searchCriteria>
  </ns1:getCampaignsByCriteria>
</SOAP-ENV:Body>

However, since I'm only setting the ids field, I'd like the SOAP body to just take into account the non-empty field(s) to look like this:

<SOAP-ENV:Body>
  <ns1:getCampaignsByCriteria>
     <searchCriteria xsi:type="ns1:CampaignSearchCriteria">
        <ids xsi:type="ns1:ArrayOf_xsd_long">123</ids>
     </searchCriteria>
  </ns1:getCampaignsByCriteria>
</SOAP-ENV:Body>

I couldn't find how you can choose which field to include when you're using a custom argument to your method. Any thoughts?

Charles Menguy
  • 40,830
  • 17
  • 95
  • 117

1 Answers1

0

how your SOAP request looks depends on your WSDL, specifically on the data type definitions which specify the schema for your message.
so you can't just omit some fields or the message won't be a valid request anymore if the schema doesn't allow it.

if i'm correct then this should be the wsdl we're talking about, for all attributes minOccurs isn't present, which means it defaults to 1 and you can't omit the elements, althoug they are nillable.

my general advise: don't think too much about how a SOAP request looks. SOAP is xml and therefore kind-of human readable, but it's not really designed to be interpreted by humans.

mata
  • 67,110
  • 10
  • 163
  • 162
  • Thanks, I was just trying to do that as the related API is throwing errors if you have empty fields in the SOAP request. I found out that since suds 0.3.8+ you can pass a dictionary of attribute/value and this will generate the appropriate request without the empty fields. And you're right about the wsdl. Thanks for the help ! – Charles Menguy May 07 '12 at 17:30