4

I am making calls to a SOAP API using suds, which returns data as objects rather than raw XML. I want to save a copy of the raw response in addition to what I parse, with the end goal being storage as JSON (I'm currently using TinyDB for testing).

The overall flow looks like this:

  1. Retrieve raw response
  2. Create a dict of the raw response using the script below
  3. Parse response objects for later use
  4. Serialize everything to JSON and store in TinyDB

My script for converting a suds object to a dict is:

def makeDict(response):
    out = {}
    for k, v in asdict(response).iteritems():
        if hasattr(v, '__keylist__'):
            out[k] = makeDict(v)
        elif isinstance(v, list):
            out[k] = []
            for item in v:
                if hasattr(item, '__keylist__'):
                    out[k].append(makeDict(item))
                else:
                    out[k].append(item)
        else:
            out[k] = v
    return out

However, sometimes when I run makeDict(object) and try to serialize to JSON, I get a type error like the following:

  File "C:\Python27\Lib\json\encoder.py", line 184, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: (Date){
   Day = 7
   Month = 8
   Year = 2004
 } is not JSON serializable

This error is throwing me off because:

  1. I know this object Date appears in other records that don't throw an error during serialization
  2. type(Date.Day) is an int and the field name is a string

Does anyone have an idea as to what's going on here? It looks as if it's trying to serialize the raw object, but everything I'm inserting into TinyDB has already been run through makeDict

AutomaticStatic
  • 1,661
  • 3
  • 21
  • 42
  • if performance isn't too much of an issue, I would add a few judicious json.dumps in the code and then do special handling on exceptions. For example at *out[k] = v*, near bottom, I would add *json.dumps(v)*. IIRC json isn't even very good at dates in javascript - round-tripping them goes native js date => string repr of date => string repr of date, rather than native js date again. – JL Peyret May 15 '15 at 16:31
  • 1
    http://stackoverflow.com/questions/2167894/how-can-i-pickle-suds-results - Alex Martelli explains why you cannot serialize suds – Peter M. - stands for Monica Mar 24 '16 at 22:17

1 Answers1

3

I suppose I'll answer my own question rather than delete it in case anyone else encounters this issue.

The suds object sometimes contains a list, which in turn contains other suds objects. The makeDict() function doesn't necessarily get to the deepest level of nesting, so it sometimes returns a dict containing a suds object which cannot be serialized.

AutomaticStatic
  • 1,661
  • 3
  • 21
  • 42