I have a SOAP request that takes below XML body
ProductsIditemName2.0ONETIME
I can make a successful request using Boomerang.
Now I actually want to use it in my python code. So I tried,
inputElement = client.factory.create('CreateExportJobRequest') inputElement.ExportJobTypeName = "Products" inputElement.ExportColumns.ExportColumn = ["Id", "itemName"] inputElement.Frequency = 'ONETIME' if updatedSince: inputElement.ExportFilters.ExportFilter = ['updatedSince'] t = client.service.CreateExportJob(inputElement.ExportJobTypeName, inputElement.ExportColumns, inputElement.ExportFilters, None, None, inputElement.Frequency)
I get an error,
'list' object has no attribute 'id'
Because a somewhat wrong XML request gets created
updatedSince
So I tried few other things for ExportFilter
like
inputElement.ExportFilters.ExportFilter = [{'id': 'updatedSince', 'text': updatedSince}]
and
inputElement.ExportFilters.ExportFilter = [('updatedSince', updatedSince)]
and
inputElement.ExportFilters.ExportFilter = [{'updatedSince': updatedSince}] # says, Type not found: 'updatedSince'
and
inputElement.ExportFilters.ExportFilter = [ {'key': 'updatedSince', 'value': {'key': 'eq', 'value': updatedSince}} ] # says, Type not found: 'value'
but nothing is working.
Before setting ExportFilter, it's value is in the form of
ExportFilters: (ExportFilters){ ExportFilter[] = }
Please help.
After debugging and going through some suds code, I have found the fix.
The complete code snippet of the fix:
inputElement = client.factory.create('CreateExportJobRequest') inputElement.ExportJobTypeName = "Products" inputElement.ExportColumns.ExportColumn = ["Id", "itemName"] inputElement.Frequency = 'ONETIME' if updatedSince: efilter = client.factory.create("ExportFilter") efilter._id = 'updatedSince' efilter.Text = updatedSince inputElement.ExportFilters.ExportFilter.append(efilter) t = client.service.CreateExportJob(inputElement.ExportJobTypeName, inputElement.ExportColumns, inputElement.ExportFilters, None, None, inputElement.Frequency)
Debugging: Because suds was raising TypeNotFound
exception, I looked for all the places that raise TypeNotFound
inside suds. I put debug points in my PyCharm.
I found that the start
method from Typed
class inside suds/mx/literal.py
was raising the error I was getting.
def start(self, content): # # Start marshalling the 'content' by ensuring that both the # 'content' _and_ the resolver are primed with the XSD type # information. The 'content' value is both translated and # sorted based on the XSD type. Only values that are objects # have their attributes sorted. # log.debug('starting content:\n%s', content) if content.type is None: name = content.tag if name.startswith('_'): name = '@'+name[1:] content.type = self.resolver.find(name, content.value) if content.type is None: raise TypeNotFound(content.tag) else: known = None if isinstance(content.value, Object): known = self.resolver.known(content.value) if known is None: log.debug('object has no type information', content.value) known = content.type frame = Frame(content.type, resolved=known) self.resolver.push(frame) frame = self.resolver.top() content.real = frame.resolved content.ancestry = frame.ancestry self.translate(content) self.sort(content) if self.skip(content): log.debug('skipping (optional) content:\n%s', content) self.resolver.pop() return False else: return True
So from this logic, I came to the fix.
But, It would be really great if somebody suggests a standard procedure for this.