Package gavo :: Package formats :: Module jsontable
[frames] | no frames]

Source Code for Module gavo.formats.jsontable

  1  """ 
  2  Writing tables in JSON. 
  3   
  4  We use python's built-in json engine to write an -- as yet -- ad-hoc json 
  5  format that essentially looks like this: 
  6   
  7  { 
  8          "contains": "table", 
  9          "columns": { (column metadata more or less as in VOTable) } 
 10          "data": { (rows as tuples) } 
 11          ("warnings": [...]) 
 12  } 
 13   
 14  No streaming at all is forseen for this format at this point. 
 15  """ 
 16   
 17  #c Copyright 2008-2019, the GAVO project 
 18  #c 
 19  #c This program is free software, covered by the GNU GPL.  See the 
 20  #c COPYING file in the source distribution. 
 21   
 22   
 23  import json 
 24   
 25  from gavo import base 
 26  from gavo import rsc 
 27  from gavo.formats import common 
 28   
 29   
30 -class JSONMetaBuilder(base.MetaBuilder):
31 """A MetaBuilder for mapping table meta information into our standard 32 JSON structure. 33 """
34 - def __init__(self, jsonStructure):
35 self.result = jsonStructure 36 base.MetaBuilder.__init__(self)
37
38 - def getResult(self):
39 return self.result
40
41 - def enterValue(self, value):
42 if self.curAtoms[-1]=="_warning": 43 self.result.setdefault("warnings", []).append(unicode(value)) 44 elif self.curAtoms[-1]=="_queryStatus": 45 self.result["queryStatus"] = unicode(value)
46 47
48 -def _getJSONColumns(serManager):
49 """returns a sequence of VOTable-like column description dictionaries. 50 """ 51 res = [] 52 for annCol in serManager: 53 res.append(annCol.annotations.copy()) 54 res[-1].pop("displayHint", None) 55 res[-1].pop("winningFactory", None) 56 res[-1].pop("nullvalue", None) 57 res[-1].pop("note", None) 58 return res
59 60
61 -def _getJSONParams(serManager):
62 """returns a dict of param dicts. 63 """ 64 result = { 65 'contains': "params", 66 } 67 for param in serManager.table.iterParams(): 68 if param.value is not None: 69 result[param.name] = { 70 'value': param.value, 71 'unit': param.unit, 72 'ucd': param.ucd, 73 'description': param.description,} 74 return result
75 76
77 -def _getJSONStructure(table, acquireSamples=False):
78 """returns a dictionary representing table for JSON serialisation. 79 """ 80 if isinstance(table, rsc.Data): 81 table = table.getPrimaryTable() 82 sm = base.SerManager(table, acquireSamples=acquireSamples) 83 84 result = { 85 'contains': "table", 86 'params': _getJSONParams(sm), 87 'columns': _getJSONColumns(sm), 88 'data': list(sm.getMappedTuples()), 89 } 90 table.traverse(JSONMetaBuilder(result)) 91 return result
92 93
94 -def writeTableAsJSON(table, target, acquireSamples=False):
95 """writes table to the target in ad-hoc JSON. 96 """ 97 jsonPayload = _getJSONStructure(table, acquireSamples) 98 return json.dump(jsonPayload, target, encoding="utf-8")
99 100 101 # NOTE: while json could easily serialize full data elements, 102 # right now we're only writing single tables. 103 common.registerDataWriter("json", writeTableAsJSON, "application/json", 104 "JSON", ".json") 105