Responsible for converting return values into cleanly serializable dict/tuples/lists
for JSON/XML/YAML output
'''
importinspect,collections
fromjinja2importTemplate
xmlListTemplate=Template("""<list>{% for item in items %}<item>{% for prop,val in item.iteritems() %}<{{prop}}>{{val}}</{{prop}}>{% endfor %}</item>{% endfor %}</list>""")
xmlTemplate=Template("""<item>{% for prop,val in item.iteritems() %}<{{prop}}>{{val}}</{{prop}}>{% endfor %}</item>""")
defconvertForSerialization(object):
"""Converts anything (clas,tuples,list) to the safe serializable equivalent"""
ifisinstance(object,dict):
returntraverseDict(object)
elifisClassInstance(object):
returnconvertClassToDict(object)
elifisinstance(object,collections.Iterable):
# iterable
values=[]
forvalinobject:
values.append(convertForSerialization(val))
returnvalues
else:
# return as-is
returnobject
defconvertClassToDict(clazz):
"""Converts a class to a dictionary"""
properties={}
forprop,valinclazz.__dict__.iteritems():
#omit private fields
ifnotprop.startswith("_"):
properties[prop]=val
returntraverseDict(properties)
deftraverseDict(dictObject):
"""Traverses a dict recursively to convertForSerialization any nested classes"""
newDict={}
forprop,valindictObject.iteritems():
ifinspect.isclass(val):
# call itself recursively
val=convertClassToDict(val)
newDict[prop]=val
returnnewDict
defgenerateXml(object):
"""Generates basic XML from an object that has already been converted for serialization"""
ifisinstance(object,dict):
returnstr(xmlTemplate.render(item=object.keys()))
elifisinstance(object,collections.Iterable):
returnstr(xmlListTemplate.render(items=object))
else:
raiseRuntimeError("Unable to convert to XML: %s"%object)
defisClassInstance(object):
"""Checks if a given object is a class instance"""