I have some data coming from a SOAP API using Suds which I need to parse in my Python script. Before I go off and write a parser (there is more than just this one to do):
1) Does anyone recognise what this is? It's the standard complex object datatype as returned by Suds (documentation). Should have spotted that.
2) If so, is there an existing library that I can use to convert it to a Python dictionary? How do I parse this object into a Python dict? It seems I can pass a dictionary to Suds but can't see an easy way of getting one back out.
(ArrayOfBalance){
   Balance[] = 
      (Balance){
         Amount = 0.0
         Currency = "EUR"
      },
      (Balance){
         Amount = 0.0
         Currency = "USD"
      },
      (Balance){
         Amount = 0.0
         Currency = "GBP"
      },
 }
                There is a class method called dict in suds.client.Client class which takes a sudsobject as input and returns a Python dict as output. Check it out here: Official Suds Documentation
The resulting snippet becomes as elegant as this:
from suds.client import Client
# Code to obtain your suds_object here...
required_dict = Client.dict(suds_object)
You might also want to check out items class method (link) in the same class which extracts items from suds_object similar to items method on dict. 
You can cast the object to dict(), but you still get the complex data type used by suds. So here are some helpful functions that I wrote just for the occasion:
def basic_sobject_to_dict(obj):
    """Converts suds object to dict very quickly.
    Does not serialize date time or normalize key case.
    :param obj: suds object
    :return: dict object
    """
    if not hasattr(obj, '__keylist__'):
        return obj
    data = {}
    fields = obj.__keylist__
    for field in fields:
        val = getattr(obj, field)
        if isinstance(val, list):
            data[field] = []
            for item in val:
                data[field].append(basic_sobject_to_dict(item))
        else:
            data[field] = basic_sobject_to_dict(val)
    return data
def sobject_to_dict(obj, key_to_lower=False, json_serialize=False):
    """
    Converts a suds object to a dict.
    :param json_serialize: If set, changes date and time types to iso string.
    :param key_to_lower: If set, changes index key name to lower case.
    :param obj: suds object
    :return: dict object
    """
    import datetime
    if not hasattr(obj, '__keylist__'):
        if json_serialize and isinstance(obj, (datetime.datetime, datetime.time, datetime.date)):
            return obj.isoformat()
        else:
            return obj
    data = {}
    fields = obj.__keylist__
    for field in fields:
        val = getattr(obj, field)
        if key_to_lower:
            field = field.lower()
        if isinstance(val, list):
            data[field] = []
            for item in val:
                data[field].append(sobject_to_dict(item, json_serialize=json_serialize))
        elif isinstance(val, (datetime.datetime, datetime.time, datetime.date)):
            data[field] = val.isoformat()
        else:
            data[field] = sobject_to_dict(val, json_serialize=json_serialize)
    return data
def sobject_to_json(obj, key_to_lower=False):
    """
    Converts a suds object to json.
    :param obj: suds object
    :param key_to_lower: If set, changes index key name to lower case.
    :return: json object
    """
    import json
    data = sobject_to_dict(obj, key_to_lower=key_to_lower, json_serialize=True)
    return json.dumps(data)
If there is an easier way, I would love to hear about it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With