Package yapydata :: Package datatree :: Module synjson4627 :: Class DataTreeJSON4627

Class DataTreeJSON4627

source code


Provides additional constraints for JSON based on RFC-4627.

The main point is here probably the required object or array as the root node, while RFC-7159 permits in general values.

Class Variables

Inherited from datatree.DataTree: M_ALL, M_FIRST, M_LAST

Method Details

isvalid_top(value, **kargs)
Static Method

source code 
Validate conformance of top-node to RFC-4627.
Decorators:
Overrides: datatree.DataTree.isvalid_top

__init__(self, data, **kargs)
(Constructor)

source code 
Args:
data:

Configuration data in accordance to RFC-4627:

data := <RFC-4627-type-for-json>

RFC-4627-type-for-json := (
      dict | list            # see: object, list
)

The initial data defines the permitted type of the first item within the subpath of the spanned data tree.

Thus atomic data types define a single node data tree only - new in RFC-7159.

Returns:
None / initialized object
Raises:

YapyDataDataTreeError

pass-through

Decorators:
Overrides: datatree.DataTree.__init__

__setattr__(self, name, value)

source code 

Validates types of own data attributes.

Args:
name:

Name of the attribute. Following are reserved and treated special:

  • type: str - 'data' The value is treated as the replacement of the internal data attribute. Replaces or creates the complete data of teh current instance.
value:
The value of the attribute. This by default superposes present values by replacement. Non-present are created.

Returns:

Raises:
YapyDataDataTreeError
Decorators:
Overrides: synjson.DataTreeJSON.__setattr__

__call__(self, *subpath, **kargs)
(Call operator)

source code 

Readout the value of a node, or an attribute. The name binding of the path is provided as a tuple of path items.

Args:
subpath:

The list of keys constituting a branch of a data tree. The subpath is treated as a branch of one of the nodes of a provided searchpath - which is by default the top node. The supported values are:

subpath := <list-of-node-ids>
<list-of-node-ids> := <node-id> [',' <list-of-node-ids>]
node-id := (
      str            # string:  dict
    | int            # integer: lists, tuple, dict
)

The value of the node within data:

nodeid := (
      <single-nodeid>
    | <list-of-nodeids>
    | <tuple-of-nodeids>
)
single-nodeid := <nodeid>
list-of-nodeids := '[' <nodeidlists> ']'
tuple-of-nodeids := '(' <nodeidlists> ')'
nodeidlists := <nodeid> [',' <nodeidlists>]
nodeid := (
      ItemKey
    | ListIndex
)
ItemKey := "valid dict-key"
ListIndex := "valid list-index"

The derived syntax classes may impose specific constraints. Thus it is recommended to use integers and strings only for maximum compatibility, and the ease of using mixed syntaxes:

ItemKey :=    str  # string:  dict
ListIndex :=  int  # integer: lists, tuple, dict
kargs:
searchpath:

Optional search path for the match of the provided address subpath. The provided subpath is applied to each node of the searchpath in accordance to the direction option. This provides the search and enumeration of side branches:

searchpath := <path-item-list>

path-item-list := <path-item> [, <path-item-list>]
path-item := (
      str  # item name
    | int  # item index
)

default := <top-node>

The search path entries has to be actually present by default. These could be either created by loading a complete tree structure, or by using the Capabilities.create() member. See also parameter 'strict'.

direction:

The search direction of the subpath within the searchpath. In case of multiple superpositioned attributes the first traversed match.

The provided values are:

direction := (
      up   | 0  | False # search from right-to-left
    | down | 1  | True  # search from left-to-right
)

default:= up
match:

Sets the match criteria for the search operation. Interferes with direction:

match := (
      M_FIRST | 'first'   # use first matching node
    | M_LAST  | 'last'    # use last matching node
    | M_ALL   | 'all'     # use all - iterate all matches
)

default := M_FIRST
partial:

Enables the return of partial sub paths in case the requested path is not completely present.

partial := (
      True   # when not completely present, the longest
             # existing part is returned, the completeness
             # is provided by the result attribute <partial>
    | False  # when not completely present an exception
             # is raised
)
strict:

Controls the required consistency. This comprises:

  1. the presence of the search path entries

  2. the presence of the requested subpath within the set of search paths

pysyn:

Activates full Python syntax. This in particular enables all container types of intermediate nodes for arbitrary paths. Includes tuple, set, frozenset, etc.

pysyn := (
      True   # allows all python types as container nodes
    | False  # allows list and dict only as container nodes
)

default := False
Returns:

In case of a match returns the tuple:

return := (<attr-value-path>, <attr-value>, <partial>)

attr-value-path := (
      "the list of keys of the top-down path"
    | "empty list when no item exists"        # see <complete>
)
attr-value := "value of the targeted node/attribute"
partial := (
      False   # the complete requested path
    | True    # the actually present part of the path
)

Else raises YapyDataDataTreeOidError.

Raises:

YapyDataDataTreeOidError

pass-through

Decorators:

create(self, *subpath, **kargs)

source code 
Adds constraints in accordance to RFC-7159.
Decorators:
Overrides: datatree.DataTree.create

get(self, *path)

source code 

Gets the value of the path within the member 'data':

self.data[key]
self.data[key0][key1][key2]...
Args:
key:

The value of the node within data:

key := (
      <single-key>
    | <list-of-keys>
    | <tuple-of-keys>
)
single-key := <key>
list-of-keys := '[' <keylists> ']'
tuple-of-keys := '(' <keylist> ')'
keylist := <key> [',' <keylist>]
key := (
      ItemKey
    | ListIndex
)
ItemKey := "valid dict-key"
ListIndex := "valid list-index"
Returns:

The value of the addressed node/value.

Raises:

pass-through

Decorators:

import_data(self, input, key=None, node=None, **kargs)

source code 

Reads a JSON file. This is a simple basic method for the application on the lower layers of the software stack. It is designed for minimal dependencies. The used library is the standard json package. The data is not validated.

Args:
input:

The source of the JSON string data:

input := (
       <fpname>        # file path name
    |  <file-id>       # file pointer id
    |  <io-stream>     # io stream id
)

fpname := <json-file-path-name>
json-file-path-name := (
      <file-path-name>           # with extension
    | <file-path-name> '.json'   # without extension, for multiple syntaxes
)
file-id := "open file: file_id = open(<fpname>)"
io-stream := "open io stream - io_stream = io.StreamIO(<json-string>)"
json-string := "a valid string in accordance to RFC-7159"
key:

The key for the insertion point:

node[key] = <file-data>

default := None - replace self.data,

The caller is responsible for the containment of the provided node within the data structure represented by this object. No checks are performed.

node:

The node for the insertion of the read data.:

default := <top>
Returns:
Reference to read data structure.
Raises:

YapyDataConfigError

pass-through

Decorators:
Overrides: datatree.DataTree.import_data

join(self, data, keyidx=None, hook=None)

source code 

Superposes a JSON structure onto an existing. This is a fixed mode and strategy special case of the generic method superpose(). Implemented by recursion. The reduced parameter set provides better performance on large trees while the graph parameters still could be efficiently set by default values.

The superpositioning is supported by multiple strategies defined by the parameter mode. The provided algorithm of the strategy is join, where the input data is processed on the exisiting tree by modification and creation as required.

  • branches are resolved from top to the leafs

  • missing sub-branches are created

  • missing leafs are created

  • existing leafs are replaced

This implements a last-wins strategy, thus in particular supports incremental load of configurations by raising priority.

Args:
data:

Top node of the data tree to be superposed.

keyidx:

Key or index to be used at the insertion node. If not given the insertion node is:

into dict: update by the new node
into list: append the new node

default := None
hook:

The insertion node for the new data:

when  not given: use top.

default := None
Returns:

Returns the merged data tree, raises an exception in case of failure.

Raises:

YapyDataDataTreeError

pass-through

Decorators:

Class Variable Details

match_map

Value:
{M_FIRST: 1, M_LAST: 2, M_ALL: 3, 'first': 1, 'last': 2, 'all': 3,}