Package yapydata :: Package datatree :: Module synyaml

Source Code for Module yapydata.datatree.synyaml

  1  # -*- coding: utf-8 -*- 
  2  """The *YapyData.xml* module provides *XML*. 
  3  """ 
  4   
  5  import os 
  6   
  7  import yaml 
  8   
  9  from yapydata.datatree import YapyDataTreeError 
 10  from yapydata.datatree.datatree import DataTree 
 11   
 12   
 13  __author__ = 'Arno-Can Uestuensoez' 
 14  __license__ = "Artistic-License-2.0 + Forced-Fairplay-Constraints" 
 15  __copyright__ = "Copyright (C) 2019 Arno-Can Uestuensoez" \ 
 16                  " @Ingenieurbuero Arno-Can Uestuensoez" 
 17  __version__ = '0.1.1' 
 18  __uuid__ = "60cac28d-efe6-4a8d-802f-fa4fc94fa741" 
 19   
 20  __docformat__ = "restructuredtext en" 
21 22 23 -class YapyDataYAMLError(YapyDataTreeError):
24 """Generic YAML syntax error. 25 """ 26 pass
27
28 29 -def readout_data(xval, **kargs):
30 """For API call-compliance with other syntaxes. Returns here the 31 input tree only. 32 33 Args: 34 xval: 35 The input tree from the *DataTreeYAML*- which is 36 the result from *yaml.load()*. 37 38 Returns: 39 The returns here the input *xval*. 40 41 Raises: 42 pass-through 43 44 """ 45 return xval
46
47 48 -class DataTreeYAML(DataTree):
49 """Provides YAML based read-only configuration of capabilities. 50 This in particular comprises the priority based readout 51 of values and defaults. The structure hereby includes 52 specialization by subcomponents, where the missing value 53 will be tried from the more general enclosing super 54 component. 55 56 The access to structured data trees offers various method to 57 access paths of nested node attributes. This comprises the 58 creation as well as the readout. 59 60 The following equivalent creation methods are supported, where 61 'treenode' could be either the root node, or any subordinated 62 branch:: 63 64 treenode['subnode0']['subnode1']['subnode7'] = value # dynamic items 65 66 value = treenode( 67 'subnode0', 'subnode1', 'subnode7', 68 create=True, 69 ) # dynamic items by '__call__' 70 71 value = treenode.subnode0.subnode1.subnode7 # static attribute addressing style 72 73 The following equivalent readout methods are supported, where 74 'treenode' could be either the root node, or any subordinated 75 branch:: 76 77 value = treenode['subnode0']['subnode1']['subnode7'] # dynamic items 78 value = treenode('subnode0', 'subnode1', 'subnode7') # dynamic items by '__call__' 79 value = treenode.subnode0.subnode1.subnode7 # static attribute addressing style 80 81 """ 82 83 #: defines the conversion from internal JSON data into XML 84 TOsyntaxdialect = { 85 } 86 87 #: defines the conversion from XML into internal JSON data 88 # FROMsyntaxdialect = { 89 # 'xml': { 90 # 91 # "Abdera_Convention": { 92 # "call": DataTreeYAML.readout_data, 93 # }, 94 # "Apache_Camel_Convention": { 95 # "call": DataTreeYAML.readout_data, 96 # }, 97 # "Badgerfish_Convention": { 98 # "call": DataTreeYAML.readout_data, 99 # }, 100 # "GData_Convention": { 101 # "call": DataTreeYAML.readout_data, 102 # }, 103 # "Gnome_Convention": { 104 # "call": DataTreeYAML.readout_data, 105 # }, 106 # "JsonML_Convention": { 107 # "call": DataTreeYAML.readout_data, 108 # }, 109 # "NewtonSoft_Convention": { 110 # "call": DataTreeYAML.readout_data, 111 # }, 112 # "oData_Convention": { 113 # "call": DataTreeYAML.readout_data, 114 # }, 115 # "Parker_Convention": { 116 # "call": DataTreeYAML.readout_data, 117 # }, 118 # "Spark_Convention": { 119 # "call": DataTreeYAML.readout_data, 120 # }, 121 # } 122 # } 123
124 - def __init__(self, data=None, **kargs):
125 """ 126 Args: 127 data: 128 A YAML compliant in-memory data tree:: 129 130 yaml-value := ( 131 object | array 132 | number 133 | string 134 | false | true 135 | null 136 ) 137 138 The equivalent *Python* types are - based on JSON-RFC7159 as canonical in-memory data:: 139 140 RFC-7159-type-for-json := ( 141 dict | list # see: object, array 142 | int | float # see: number 143 | str # see: unicode / for Python: ISSTR = (str(3) | unicode(2)) 144 | None | True | False # see: null, true, false 145 ) 146 147 The initial data defines the permitted type of the first item 148 within the *subpath* of the spanned data tree. 149 150 Thus atomic data types define a single node data tree only - new in RFC-7159. 151 152 Returns: 153 None / initialized object 154 155 Raises: 156 YapyDataDataTreeError 157 158 pass-through 159 160 """ 161 DataTreeYAML.isvalid_top(data) 162 super(DataTreeYAML, self).__init__(data)
163
164 - def __setattr__(self, name, value):
165 """Validates types of own data attributes. 166 167 Args: 168 name: 169 Name of the attribute. Following are reserved and 170 treated special: 171 172 * type: str - 'data' 173 The value is treated as the replacement of the internal 174 data attribute. Replaces or creates the complete data 175 of teh current instance. 176 177 value: 178 The value of the attribute. This by default superposes 179 present values by replacement. Non-present are created. 180 181 Returns: 182 183 Raises: 184 YapyDataDataTreeError 185 186 """ 187 if name == 'data': 188 # 189 # replacement of current managed data 190 # 191 # if not isinstance(value, (dict, list,)): 192 # raise YapyDataXMLError( 193 # "value must be a 'dict' == JSON-object or list == JSON-list, got: " 194 # + str(type(value)) 195 # ) 196 self.__dict__[name] = value 197 198 else: 199 # 200 # any standard attribute with standard behavior 201 # 202 return object.__setattr__(self, name, value)
203 204 @staticmethod
205 - def isvalid_top(value, **kargs):
206 """NOP""" 207 return
208
209 - def import_data(self, fpname, key=None, node=None, **kargs):
210 """Reads a YAML file. This is a simple basic method for the application 211 on the lower layers of the software stack. It is designed for minimal 212 dependencies. The used library is the *PyYaml* package. 213 214 Args: 215 fpname: 216 File path name of the *YAML* file. :: 217 218 fpname := <yaml-file-path-name> 219 yaml-file-path-name := ( 220 <file-path-name> # with extension 221 | <file-path-name> '.yaml' # without extension, for multiple syntaxes 222 ) 223 224 key: 225 The key for the insertion point:: 226 227 node[key] = <file-data> 228 229 default := None - replace self.data, 230 231 The caller is responsible for the containment of the provided 232 node within the data structure represented by this object. No 233 checks are performed. 234 235 node: 236 The node for the insertion of the read data.:: 237 238 default := <top> 239 240 Returns: 241 Reference to read data structure. 242 243 Raises: 244 YapyDataConfigError 245 246 pass-through 247 248 """ 249 if not os.path.isfile(fpname): 250 if not os.path.isfile(fpname + '.yaml'): 251 raise YapyDataTreeError("Missing file: " + str(fpname)) 252 else: 253 fpname = fpname + '.yaml' 254 255 datafile = os.path.abspath(fpname) 256 with open(datafile) as data_file: 257 xval = yaml.load(data_file) 258 jtree = xval 259 260 if key and node == None: 261 raise YapyDataTreeError("Given key(%s) requires a valid node." % (str(key))) 262 263 if key: 264 node[key] = jtree 265 else: 266 self.data = jtree 267 268 return jtree
269