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