Complex Python JSON object to custom dictionary conversion -


i have following json object -

{     "resource": [         {             "@name": "bravo",             "@signature": "h#bravo",             "@type": "esx_5.x",             "@typedisplayname": "esx server",             "perflist": {                 "@attrid": "cpuusage",                 "@attrname": "usage",                 "data": [                     {                         "@data": "26.00",                         "@end": "01:05:00",                         "@interval": "60",                         "@start": "01:04:00"                     },                     {                         "@data": "24.00",                         "@end": "01:04:00",                         "@interval": "60",                         "@start": "01:03:00"                     },                     {                         "@data": "36.00",                         "@end": "01:03:00",                         "@interval": "60",                         "@start": "01:02:00"                     },                     {                         "@data": "38.00",                         "@end": "01:02:00",                         "@interval": "60",                         "@start": "01:01:00"                     },                     {                         "@data": "37.00",                         "@end": "01:01:00",                         "@interval": "60",                         "@start": "01:00:00"                     }                 ]             },             "resource": [                 {                     "@name": "tango",                     "@signature": "vm#tango",                     "@type": "vm",                     "@typedisplayname": "virtual machine",                     "perflist": {                         "@attrid": "cpuusage",                         "@attrname": "usage",                         "data": {                             "@data": "12.00",                             "@end": "04:05:00",                             "@interval": "60",                             "@start": "04:04:00"                         }                     }                 },                 {                     "@name": "charlie",                     "@signature": "vm#charlie",                     "@type": "vm",                     "@typedisplayname": "virtual machine",                     "perflist": {                         "@attrid": "cpuusage",                         "@attrname": "usage",                         "data": [                             {                                 "@data": "12.00",                                 "@end": "04:20:00",                                 "@interval": "60",                                 "@start": "04:19:00"                             },                             {                                 "@data": "12.00",                                 "@end": "04:19:00",                                 "@interval": "60",                                 "@start": "04:18:00"                             }                         ]                     }                 }             ]         },         {             "@name": "alpha",             "@signature": "h#alpha",             "@type": "esx_5.x",             "@typedisplayname": "esx server",             "perflist": [                 {                     "@attrid": "cpuusage",                     "@attrname": "usage",                     "data": {                         "@data": "9",                         "@end": "06:10:00",                         "@interval": "60",                         "@start": "06:09:00"                     }                 },                 {                     "@attrid": "cpuusagemhz",                     "@attrname": "usage mhz",                     "data": {                         "@data": "479",                         "@end": "06:10:00",                         "@interval": "60",                         "@start": "06:09:00"                     }                 }             ]         }     ] } 

i looking json traversal reach keys , convert above following expected python dictionary -

d = { 'esx_5.x' :          {              'bravo' :                 {                     "@typedisplayname" : "esx server",                     "@signature" : "h#bravo",                     "cpuusage" :                         {                             "from_01:04:00_to_01:05:00" : 26.00,                             "from_01:03:00_to_01:04:00" : 24.00,                             "from_01:02:00_to_01:03:00" : 36.00,                             "from_01:01:00_to_01:02:00" : 38.00,                             "from_01:00:00_to_01:01:00" : 37.00,                             "interval" : 60                         },                     "vm" :                         {                             "tango" :                                 {                                     "@typedisplayname" : "virtual machine",                                     "@signature" : "vm#tango",                                     "cpuusage" :                                         {                                             "from_04:04:00_to_04:05:00" : 12.00,                                             "interval" : 60                                         }                                 },                             "charlie" :                                 {                                     "@typedisplayname" : "virtual machine",                                     "@signature": "vm#charlie",                                     "cpuusage" :                                          {                                             "from_04:19:00_to_04:20:00" : "12.00",                                             "from_04:18:00_to_04:19:00" : "12.00",                                             "@interval": "60",                                         }                                 }                         },                 },             'alpha' :                 {                     "@typedisplayname" : "esx server",                     "@signature" : "h#alpha",                     "cpuusage" :                         {                             "from_06:09:00_to_06:10:00" : 9,                             "@interval": "60"                         },                     "cpuusagemhz" :                         {                             "from_06:09:00_to_06:10:00" : 479,                             "@interval": "60"                         }                 }         }     } 

need recursive functions fetch resources & perflist & data , customize dictionary.

there possible typos/syntax_errs in hand cooked expected dictionary...

here code far -- failing n number of nested resources.

import json  class mqlprettyprint():     key_response = 'response'     key_results = 'results'     key_resource = 'resource'      def __init__(self,file=none):         self._json_file = file         self._json_data = self.read_json_file()         self._json_dict = self.json_to_dict()      def json_file(self):         return self._json_file      def read_json_file(self):         json_data = ""         try:             json = open(self._json_file,"r")             json_data = json.read()             json.close()         except:             raise          return json_data      def json_to_dict(self):         return json.loads(self._json_data)      def json_data(self):         return self._json_data      def json_dict(self):         return self._json_dict      def json2mql(self):         key in self._json_dict:             if key == self.key_response:                 val = self._json_dict[key]                 response = self.fetch_response(val)      def fetch_response(self,dict):         key in dict:             if key == self.key_results:                 val = dict[key]                 results = self.fetch_results(val)      def fetch_results(self,dict):         key in dict:             if key == self.key_resource:                 val = dict[key]                 resource = self.fetch_resource(val)      def fetch_resource(self,resources,dict={}):         if isinstance(resources,list):             resource in resources:                 print "\n\n",resource                 if isinstance(resource,__builtins__.dict):                     #header = self.fetch_resource_header(resource)                     #perflist = self.fetch_perf_list(resource)                     self.fetch_resource(resource)         elif isinstance(resources,dict):             header = self.fetch_resource_header(resource)             perflist = self.fetch_perf_list(resource)         else:             print resources      def fetch_resouce_header(resource):         name = resource['@name']         signature = resource['@signature']         type = resource['@type']         typedisplayname = resource['@typedisplayname']         resource_dict = {'@name' : name,                          '@signature' : signature,                          '@type' : type,                          '@typedisplayname' : typedisplayname}         return resource_dict      def fetch_perf_list(self,resource,perfdict={}):         perflists = resource['perflist']         if isinstance(perflists,list):             perf in perflists:                 self.fetch_perf_list(perf,perfdict)         elif isinstance(perflists,dict):             header = self.fetch_perf_header(perf)             datalist = self.fetch_data(perf)             key = ""             if len(perfdict) == 0:                 key = header['@attrid']                 perfdict[key] = header                 perfdict[key]['data'] = datalist             else:                 if not perfdict.has_key(key):                     perfdict[key] = header                     perfdict[key]['data'] = datalist                 else:                     if perfdict.has_key('data'):                         perfdict[key]['data'].update(datalist)                     else:                         perfdict[key]['data'] = datalist         else:             print perflists         return perfdict       def fetch_perf_header(self,perfdict):         header = {}         attrid = perfdict['@attrid']         attrname = perfdict['@attrname']         header = {'@attrid' : attrid,                   '@attrname' : attrname}         return header      def fetch_data(self,perfdict,datadict={}):         datalist = perfdict['data']         if isinstance(datalist,list):             data in datalist:                 #fetch internal data                 self.fetch_data(data,datadict)         elif isinstance(datalist,dict):             start = datalist['@start']             end = datalist['@end']             interval = datalist['@interval']             data = datalist['@data']             key = "%s_%s" % (start,end)             datadict[key] = datalist             #data_dict = {key : datalist}             #if len(datadict) == 0:             #    datadict[key] = data_dict             #else:             #    datadict['data'].update(data_dict)         else:             print datalist         return datadict 

sometimes when operating on nested structures using recursive functions, easier think in terms of walking function , operation function. want target dicts contained in json structure , perform transformation operation on them.

transforming structure in-place, instead of recreating new one, easier when dealing nests. more difficult approach of constructing nested dicts json structure involves being able address specific json elements, place them @ correct depth , branch of new structure; involves 2 parallel walking operations.

one thing mindful of though, modifying nested structure while walking across transformation operation may change list walking function iterating on. in instance, children (not siblings) modified first before walking on lower branches.

from copy import deepcopy import json pprint import pprint stringio import stringio  json_str = \ ''' {     "resource": [         {             "@name": "bravo",             "@signature": "h#bravo",             "@type": "esx_5.x",             "@typedisplayname": "esx server",             "perflist": {                 "@attrid": "cpuusage",                 "@attrname": "usage",                 "data": [                     {                         "@data": "26.00",                         "@end": "01:05:00",                         "@interval": "60",                         "@start": "01:04:00"                     },                     {                         "@data": "24.00",                         "@end": "01:04:00",                         "@interval": "60",                         "@start": "01:03:00"                     },                     {                         "@data": "36.00",                         "@end": "01:03:00",                         "@interval": "60",                         "@start": "01:02:00"                     },                     {                         "@data": "38.00",                         "@end": "01:02:00",                         "@interval": "60",                         "@start": "01:01:00"                     },                     {                         "@data": "37.00",                         "@end": "01:01:00",                         "@interval": "60",                         "@start": "01:00:00"                     }                 ]             },             "resource": [                 {                     "@name": "tango",                     "@signature": "vm#tango",                     "@type": "vm",                     "@typedisplayname": "virtual machine",                     "perflist": {                         "@attrid": "cpuusage",                         "@attrname": "usage",                         "data": {                             "@data": "12.00",                             "@end": "04:05:00",                             "@interval": "60",                             "@start": "04:04:00"                         }                     }                 },                 {                     "@name": "charlie",                     "@signature": "vm#charlie",                     "@type": "vm",                     "@typedisplayname": "virtual machine",                     "perflist": {                         "@attrid": "cpuusage",                         "@attrname": "usage",                         "data": [                             {                                 "@data": "12.00",                                 "@end": "04:20:00",                                 "@interval": "60",                                 "@start": "04:19:00"                             },                             {                                 "@data": "12.00",                                 "@end": "04:19:00",                                 "@interval": "60",                                 "@start": "04:18:00"                             }                         ]                     }                 }             ]         },         {             "@name": "alpha",             "@signature": "h#alpha",             "@type": "esx_5.x",             "@typedisplayname": "esx server",             "perflist": [                 {                     "@attrid": "cpuusage",                     "@attrname": "usage",                     "data": {                         "@data": "9",                         "@end": "06:10:00",                         "@interval": "60",                         "@start": "06:09:00"                     }                 },                 {                     "@attrid": "cpuusagemhz",                     "@attrname": "usage mhz",                     "data": {                         "@data": "479",                         "@end": "06:10:00",                         "@interval": "60",                         "@start": "06:09:00"                     }                 }             ]         }     ] } '''  def walk_fun_lim(ilist, func=none):     '''     recursively walk nested list , dict structure, running func on dicts     '''     def walk_fun_lim_helper(ilist, func=none, count=0):         tlist = []         ttlist = []         if(isinstance(ilist, list)):             ttlist = filter(lambda x: x, func(filter(lambda x: isinstance(x, dict), ilist)))             if(ttlist):                 tlist += ttlist             q in ilist:                 ttlist = filter(lambda x: x, walk_fun_lim_helper(q, func, count+1))                 if(ttlist):                     tlist += ttlist         elif(isinstance(ilist, dict)):             ttlist = filter(lambda x: x, func([ilist]))             if(ttlist):                 tlist += ttlist             q in ilist:                 ttlist = filter(lambda x: x, walk_fun_lim_helper(ilist[q], func, count+1))                 if(ttlist):                     tlist += ttlist         return [tlist] if(count != 0) else tlist     if(func != none , hasattr(func, "__call__")):         return walk_fun_lim_helper(ilist, func)     else:         return []  def transformers_robots_in_disguise(x):     idict in x:         plist = idict.pop("perflist", [])         plist = plist if(isinstance(plist, list)) else [plist]         sub_dict in plist:             sub_name = sub_dict.pop("@attrid")             dlist = sub_dict.pop("data", [])             dlist = dlist if(isinstance(dlist, list)) else [dlist]             new_dict = {}             sub_dict in dlist:                 new_dict["from_%(@start)s_to_%(@end)s" % sub_dict] = sub_dict["@data"]                 new_dict["@interval"] = sub_dict["@interval"]             idict[sub_name] = new_dict         rlist = idict.pop("resource", [])         rlist = rlist if(isinstance(rlist, list)) else [rlist]         sub_dict in rlist:             sub_type = sub_dict.pop("@type")             sub_name = sub_dict.pop("@name")             idict.setdefault(sub_type, {})[sub_name] = sub_dict     return []  json_data = json.load(stringio(json_str)) data_copy = deepcopy(json_data) walk_fun_lim(data_copy, transformers_robots_in_disguise) pprint(data_copy) 

Comments