‘jsondata’ - package

The package ‘jsondata’ is aimed for the management of modular in-memory data structures based on JSON. The data is foreseen to be represented by a main data tree with dynamically added and/or removed branches. The branches of data structures in particular provide for custom data. The data could either be related to a module, and/or to specific classes. The components provides by the package are:

  • JSONData

    The main class JSONData provides for the core interface of the integration of JSON based documents and sub-documents including the validation by JSONschema - RFC7159/RFC4629 and DRAFT4schema. This provides for dynamic incremental construction of data and the persistent storage of the modified tree. The data is organized into trees and branches managed by the packages ‘json’ and ‘jsonschema’.

  • JSONDataSerializer

    The class JSONDataSerializer derived from JSONData provides for serialization and integration of documents and sub-documents. This provides for the persistent storage of modified document trees.

  • JSONPointer

    The JSONPointer module provides for addressing of components within JSON based data structures in accordance to RCF7159 and RFC6901. The integrated caching of the in-memory address of the pointed node provides for native speed in case of repetition, aimed for nested hierarchical loop constructs. The class JSONPointer in particular provides operators for pointer arithmetics in order to simplify the application of navigation and loop constructs.

  • JSONPatch

    The JSONPatch module provides features for the alteration of JSON based data structures in accordance to RFC6902. The close design enables the fast addressing by combined usage with the class JSONPointer. The class JSONPatch in particular provides operators for patch arithmetics in order to simplify the modular patch management and loop constructs. The patch task lists could be assembled by modules, modified as required and stored persistently for reuse.

  • JSONCompute

    Moved to a seperate package ‘jsoncompute’.

  • Selftest / ‘jsondc –selftest’

    Last but not least, the selftest feature provides for a quick verification of the package itself.

The close design to the presented in-memory interface by the packages ‘json’ and ‘jsonschema’ provides for reliable and fast access based on the standard Python packages, while the ‘jsondata’ package adds high-level abstractions provided by standards for addressing and data assembly. The native Python access to the data entries remains compatible, while due to the caching of in-memory addresses of the nodes the access by the ‘jsondata’ add-ons is close to native Python performance.

The package ‘jsondata’ supports the standards RFC6901, RFC6902, and the integration of RFC7159 with DRAFT4Schema, while relying for the syntax primitives of underlying layers presented by the packages ‘json’ and ‘jsonschema’. The JSON language primitives for JSON are conform with related ECMA and RFC standards and proposals. Here ECMA-262, ECMA-404, RFC7159/RFC4627, ‘draft-zyp-json-schema-04’, and others.

JSON based data provides for low resource data structure descriptions, thus fits in general quite good to distributed interface APIs, beneath JavaScript itself to protocols like those based on REST. But it also is applicable in case of numerous other requirements, a typical application for branch data is the persistent storage of GUI models for dynamically loaded and released user elements.

The core module ‘jsondata.JSONData’ provides hereby the load of a master model from a JSON file, and the incremental addition and removal of branches to the model by loading additional JSON modules into the master model. This is accompanied by the additional modules of this package, e.g. for modification in accordance to standards, or persistency of the in-memory data. The implementation is based on the standard packages ‘json’ and ‘jsonschema’. The workflow provided by this package is:

  1. Create the initial in-memory data model by loading the master JSON data. Decide here to use validation or not. Even though the validation itself could be shifted to a later state, once the data is loaded it may alter the state of the application irreversible.
  2. Add/insert an arbitrary number of branches provided e.g. by plugins into an arbitrary position of the data model. Now for the branch decide whether to validate or not.

The data could be validated by provided JSONschema files. The interface supports for various types of branch insertion and deletion. The supported data resulting into a tree-structure could be depicted as:

root-node
    |
APP-schema
    +- <= import/export A-branches <-> API-schema + A-schema
    |
    +- <= import/export B-branches <-> API-schema + B-schema
    |
    `- <= import/export C-branches <-> API-schema + C-schema

In case of requested validation of multiple components various schema files are required. The main schema for the application ‘APP-schema’ has to be provided for the core application.

The APP-schema provides in case of persistent configuration data the structural model for the statically related data of the application code. The ‘datafile’ with values, e.g. altered by user interaction, could be varied and superposed as required, as long as the structure is valid. The import interface represented in ‘API-schema’ is for the case of validation mandatory too. This ensures valid interface data is imported into the application. Whereas the specific schema files(A,B,C-schema) depend on the actual implementation of the imported modules. The resulting data could be saved for later reuse.

‘jsondata.JSONData’ - Module

Core features for the processing of structured JSON based in-memory data. This comprises the load of a master model from a JSON file, and the incremental addition and removal of branches by loading additional JSON modules into the master model. The resulting data could be saved for later reuse, where complex configuration is varied by user interaction. The implementation is based on the standard packages ‘json’ and ‘jsonschema’.

This module uses for the syntax of JSON data either a preloaded module, or loads the standard module by default. Current supported packages are:

  • json: The standard json package of the Python distribution.

  • ujson: ‘Ultra-JSON’, a wrapped C implementation with

    high-performance conversion.

The current default module is ‘json’ for syntax processing, the standard package ‘jsonschema’ for the optional validation.

Constants

Compliance modes

  • MODE_JSON_RFC4927 = 0: Compliant to IETF RFC4927.
  • MODE_JSON_RF7951 = 2: Compliant to IETF RF7951.
  • MODE_JSON_ECMA264 = 10: Compliant to ECMA-264, refer to Chapter 15.12 The JSON Object.
  • MODE_POINTER_RFC6901 = 20: Compliant to IETF RFC6901.
  • MODE_PATCH_RFC6902 = 30: Compliant to IETF RFC6902.
  • MODE_SCHEMA_DRAFT3 = 43: Compliant to IETF DRAFT3.
  • MODE_SCHEMA_DRAFT4 = 44: Compliant to IETF DRAFT4.

Types of validator

  • OFF = 0: No validation.
  • DRAFT4 = 1: Use draft4: jsonschema.validator(Draft4Validator)
  • DRAFT3 = 2: Use draft3:jsonschema.Draft3Validator

The default value is:

  • DEFAULT = DRAFT4 = 1: Default

Match Criteria

Match criteria for node comparison:

  • MATCH_INSERT = 0: for dicts
  • MATCH_NO = 1: negates the whole set
  • MATCH_KEY = 2: for dicts
  • MATCH_CHLDATTR = 3: for dicts and lists
  • MATCH_INDEX = 4: for lists
  • MATCH_MEM = 5: for dicts(value) and lists
  • MATCH_NEW = 6: for the creation of new

Return Sets

  • FIRST: The first match only.
  • ALL: All matches.

JSONData

class jsondata.JSONData.JSONData(*args, **kargs)[source]

Representation of a JSON based object data tree.

This class provides for the handling of the in-memory data by the main hooks ‘data’, and ‘schema’. This includes generic methods for the advanced management of arbitrary ‘branches’ in extension to RCF6902, and additional methods strictly compliant to RFC6902.

Due to the pure in-memory support and addressing by the enclosed module JSONPointer for RFC6901 compliant addressing by in memory caching, the JSONData may outperform designs based on operation on the native JSON representation.

Attributes:
data: The data tree of JSON based objects provided
by the module ‘json’.
schema: The validator for ‘data’ provided by
the module ‘jsonschema’.
Common call parameters provided by the methods of this class are:
targetnode := addressreference
The target node of called method. The ‘targetnode’ in general represents the target of the called method. In most cases this has to be a reference to a container for the modification and/or insertion of resulting elements. The methods require the change of contained items, which involves the application of a ‘key’ pointing to the hook in point of the reference to the modification.
key := key-value
The hook-in point for references of modified entries within the targetnode container. The following values are supported:
sourcenode := addressreference
The in-memory node address of the source branch for the method, e.g. ‘copy’ or ‘move’ operation.

The address references supported in this class refer the resulting in-memory representation of a pointer path. The target is a node within a Python data representation as provided by the package ‘json‘ and compatible packages, e.g. ‘ujson‘. The supported input syntax is one of the following interchangeable formats:

# The reference to a in-memory-node.
addressreference := (
      nodereference
    | addressreference-source
)

nodereference:= (
      <in-memory>
    | ''
)

<in-memory> := "Memory representation of a JSON node, a 'dict'
    or a 'list'. The in-memory Python node reference has to be
    located within the document, due to performance reasons this
    is not verified by default.
    
    The 'nodereference' could be converted from the
    'addressreference-source' representation."

'' := "Represents the whole document in accordance to RFC6901.
    Same as 'self.data'." 

# The source of the syntax for the description of the reference
# pointer path to a node. This is applicable on paths to be created.
addressreference-source := (
    JSONPointer
)
      
JSONPointer:="A JSONPointer object in accordance to RFC6901.
    for additional information on input formats refer to the 
    class documentation.
    This class provides a fully qualified path pointer, which
    could be converted into any of the required representations."

For hooks by ‘key-value’ within addressed containers:

key-value:=(None|<list-index>|<dict-key>) 
    
None := "When the 'key' parameter is 'None', the action 
    optionally could be based on the keys of the 'sourcenode'.  
    The contents of the branch replace the node contents
    when the type of the branch matches the hook."

<list-index>:=('-'|int)

<dict-key>:="Valid for a 'dict' only, sets key/value pair, 
    where present is replace, new is created."

'-' := "Valid for a 'list' only, appends to present."

int := "Valid for a 'list' only, replaces present when
    0 < #int < len(Node)."

In the parameter lists of methods used term ‘pointer’ is either an object of class ‘JSONPointer’, or a list of pointer path entries.

The JSON types ‘object’ and ‘array’ behave in Python slightly different in accordance to RFC6902. The main difference arise from the restrictions on applicable key values. Whereas the ranges are limited logically by the actual container sizes, the object types provide free and unlimited keys. The limit is set by type restriction to unicode and ‘non-nil’ only for keys.

Attributes

  • JSONData.data: JSON object data tree.
  • JSONData.schema: JSONschema object data tree.

Methods

__init__
JSONData.__init__(*args, **kargs)[source]

Loads and validates a JSON definition with the corresponding schema file.

Args:
args*: Optional position parameters, these branch_replace corresponding key
parameters.

data

**kargs:

data: JSON data within memory.

default:= None

indent_str: Defied the indentation of ‘str’.

default:= 4

interactive: Hints on command line call for optional change of display format.

default:= False

schema: A valid in-meory JSONschema.

default:= None
validator: [default, draft3, draft4, on, off, ]

Sets schema validator for the data file. The values are: default=validate, draft3=Draft3Validator, off=None

default:= off

printdata: branch=None

Pretty print resulting final data of branch.

default:= top

printschema: branch=None

Pretty print resulting schema.

default:= top

debug: Displays extended state data for developers.
Requires __debug__==True.
verbose: Extends the amount of the display of
processing data.
Returns:
Results in an initialized object.
Raises:

NameError:

JSONDataValue:

jsonschema.ValidationError:

jsonschema.SchemaError:

__repr__
JSONData.__repr__()[source]

Dump data.

__str__
JSONData.__str__()[source]

Dumps data by pretty print.

branch_add
JSONData.branch_add(targetnode, key, sourcenode)[source]

Add a complete branch into a target structure of type object.

Present previous branches are replaced, non-existent branches are added. The added branch is created by a deep copy, thus is completely independent from the source.

Call: branch_add ( t, k, s )

i target source add type
t k s from to
0 node key node s t[k] any
1 node None node s t[*] match
  1. Use-Case-0: Any source node type is added as ‘t[k]’.

  2. Use-Case-1: The content keys of node ‘s’ are added each

    to the node ‘t’. Therefore the node types of ‘s’ and ‘t’ have to match.

    This behaviour is defined in respect to the parameter passing of Python.

Args:
targetnode := nodereference
Target container node where the branch is to be inserted.
key := key-value
Hook for the insertion within target node.
sourcenode := nodereference
Source branch to be inserted into the target tree.
Returns:
When successful returns ‘True’, else returns either ‘False’, or raises an exception.
Raises:
JSONDataNodeType: JSONDataKeyError:
branch_copy
JSONData.branch_copy(targetnode, key, sourcenode, force=True)[source]

Copies the source branch to the target node.

The copy is internally mapped onto the ‘branch_add’ call, thus shares basically the same parameters and behaviour. Due to the required modification of the target only, the copy is slightly different from the ‘branch_move’ call.

Call: branch_copy ( t, k, s )

i target source copy type
t k s from to
0 node key node s t[k] any
1 node None node s t[sk] match
For the description of the Use-Cases refer to branch_add.
Args:
targetnode := nodereference
Target tree the branch is to be inserted.
key := key-value
Key of insertion point within target node.
sourcenode := nodereference
Source branch to be inserted into target tree.
force: If true present are replaced, else only non-present

are copied.

default:=True

Returns:
When successful returns ‘True’, else returns either ‘False’, or raises an exception.
Raises:
JSONData:
branch_create
JSONData.branch_create(targetnode, branch, value=None)[source]

Creates a branch located at targetnode.

The requested branch as created as child value of provided ‘targetnode’. ‘targetnode’ is required to exist.

REMARK: Current version relies for the created nodes on the
content type of the key(str,unicode)/index(int), later versions may use a provided schema.

Call: branch_create ( t, b, v )

i target branch value
t b v
0 node list [any]
1 node list [any]
2 node pointer [any]
3 node pointer [any]
Args:
targetnode := nodereference
Base node for the insertion of branch.
branch := addressreference-source
New branch to be created in the target tree. A Pointer address path relative to the ‘targetnode’.
value: Optional value for the leaf. The value itselfn
could be either an atomic type, or a branch itself in accordance to RFC6902.
Returns:
When successful returns the leaf node, else returns either ‘None’, or raises an exception.
Raises:
JSONData:
branch_move
JSONData.branch_move(targetnode, key, sourcenode, skey, force=True, forcext=False)[source]

Moves a source branch to target node.

Moves by default only when target is not yet present. The parameters for ‘list’, ‘force’ enabled to overwrite, whereas the parameter ‘forcext’ enables to move all entries and extend the target items.

Due to the Python specific passing of flat parameters as a copy of the reference without access to the actual source entry, these are slightly different from the ‘branch_copy’ and ‘branch_add’ methods modifying the target only. Therefore additional source keys ‘skey’ are required by ‘move’ in order to enable the modification of the source entry.

Call: branch_move ( t, k, s, sk )

i target source move type
t k s sk from to
0 node key node key s[sk] t[k] any
1 node None node key s[sk] t[sk] match
  1. Use-Case-0: Moves any.

  2. Use-Case-1: Moves matching key types only: list-to-list,

    or dict-to-dict.

Args:
targetnode := nodereference
Target tree the branch is to be inserted.
key := key-value
Key of insertion point within target node.
sourcenode := nodereference
Source branch to be inserted into target tree.
skey := key-value
Key of the source to be moved to target node.
force: If true present are replaced, else only

non-present are moved.

default:=True

forcext: If true target size will be extended when

required. This is applicable on ‘list’ only, and extends RFC6902. The same effect is given for a ‘list’ by one of:

  • key:=’-‘
  • key:=None and skey:=’-‘
Returns:
When successful returns ‘True’, else returns either ‘False’, or raises an exception.
Raises:
JSONData: JSONDataKey: KeyError:
branch_remove
JSONData.branch_remove(targetnode, key)[source]

Removes a branch from a target structure.

The corresponding elements of the ‘targetnode’ tree are removed. The remaining are kept untouched. For tree nodes as leafs the whole corresponding subtree is deleted.

REMARK: No reference checks are done, so the user is responsible
for additional references.

Call: branch_remove ( t, k )

i target remove type
t k branch
0 node key t[k] any
1 node None t[*] any
  1. Use-Case-0: Removes any type of node.
  2. Use-Case-1: Removes all contained items of any type.
Args:
targetnode := nodereference
Container of ‘targetnode’ with items to be removed.
key := key-value
The item to be removed from the ‘targetnode’. When ‘None’, all contained items are removed.
Returns:
When successful returns ‘True’, else returns either ‘False’, or raises an exception.
Raises:
JSONDataException:
branch_replace
JSONData.branch_replace(targetnode, key, sourcenode)[source]

Replaces the value of the target node by the copy of the source branch.

Requires in order to RFC6902, all items to be replaced has to be present. Thus fails if at least one is missing.

Internally the ‘branch_add()’ call is used with a deep copy. When a swallow copy is required the ‘branch_move()’ has to be used.

Args:
targetnode := nodereference
Target tree the branch is to be inserted.
key := key-value
Key of insertion point within target node. If key==None, the whole set of keys is replaced by the content of the ‘sourcenode’.
sourcenode := nodereference
Source branch to be inserted into target tree.
force: If true present are replaced, else only non-present
are copied.
Returns:
When successful returns ‘True’, else returns either ‘False’, or raises an exception.
Raises:
JSONData:
branch_test
classmethod JSONData.branch_test(targetnode, value)[source]

Tests match in accordance to RFC6902.

Args:
targetnode := a valid node
Node to be compared with the value. Due to ambiguity the automated conversion is not reliable, thus it has to be valid.

value: Expected value for the given node.

Returns:
When successful returns ‘True’, else returns ‘False’.
Raises:
JSONData:
getData
JSONData.getData()[source]

Returns the reference to data.

getPointerPath
classmethod JSONData.getPointerPath(node, base, restype=1)[source]

Converts a node address into the corresponding pointer path.

The current implementation is search based, thus may have performance issues when frequently applied.

Args:

node: Address of Node to be searched for.

base: A tree top nodes to search for node.

restype: Type of search.

first: The first match only.

all: All matches.

Returns:

Returns a list of lists, where the contained lists are pointer path-lists for matched elements.

  • restype:=FIRST: ‘[[<first-match>]]’,
  • restype:=ALL: ‘[[<first-match>],[<second-match>],...]’
Raises:
JSONData:
getSchema
JSONData.getSchema()[source]

Returns the reference to schema.

getTreeDiff
classmethod JSONData.getTreeDiff(n0, n1, difflst=None, alldifs=False, dl=0, path='')[source]

Recursive tree compare for Python trees as used for the package ‘json’.

Finds diff in native Python trees assembled by the standard package ‘json’ and compatible, e.g. ‘ujson’.

getValueNode
isApplicable
JSONData.isApplicable(targetnode, key, branch, matchcondition=None, **kargs)[source]

Checks applicability by validation of provided match criteria.

The contained data in ‘datafile’ could be either the initial data tree, or a new branch defined by a fresh tree structure. The ‘targetnode’ defines the parent container where the new branch has to be hooked-in.

Args:
targetnode:
Target container hook for the inclusion of the loaded branch. The branch is treated as a child-branch, hooked into the provided container ‘targetnode’.
branch:
Branch to be imported into the target container. The branch is treated as a child-branch.
matchcondition:

Defines the criteria for comparison of present child nodes in the target container. The value is a list of critarias combined by logical AND. The criteria may vary due to the requirement and the type of applied container: - common: Common provided criteria are:

  • insert: Just checks whether the branch could be inserted.

    In case of ‘list’ by ‘append’, in case of a ‘dict’ by the insert-[]-operator. This is in particular foreseen for the initial creation of new nodes.

  • present: Checks whether all are present.

  • no: Inverts the match criteria for the whole current set.

  • dict: The provided criteria are:
    • key: Both share the same key(s).

    • child_attr_list: A list of child attributes to be matched.

      This may assure e.g. compatibility by a user defined ID, and or a UUID.

    default:=[‘key’,]

  • list: The provided criteria are:
    • index: The positions of source and target have to match.

    • child_attr_list: A list of child attributes to be matched,

      thus e.g. the ‘key’ of dictionaries could be emulated by an arbitrary attribute like ‘mykey’. This may assure e.g. compatibility by a user defined ID, and or a UUID.

    • mem: Checks whether the in-memory element is already present.

      Even though this is a quite weak criteria, it is probably the only and one common generic criteria for lists.

    default:= mem # ATTENTION: almost any call adds a branch!

**kargs:
childattrlist: A list of user defined child attributes which

all together(AND) define the match criteria.

default:=None, returns ‘True’

Returns:

When successful returns ‘True’, else returns either ‘False’, or raises an exception.

The rule of thumb is:
  • type-mismatch: Exception
  • value-mismatch: return False

Success is: no-defined-condition or no-failing-condition

Raises:

JSONData:

JSONDataValue:

printData
JSONData.printData(pretty=True, **kargs)[source]

Prints structured data.

Args:

pretty: Activates pretty printer for treeview, else flat.

sourcefile: Loads data from ‘sourcefile’ into ‘source’.

default:=None

source: Prints data within ‘source’.

default:=self.data
Returns:
When successful returns ‘True’, else returns either ‘False’, or raises an exception.
Raises:

JSONDataAmbiguity:

forwarded from ‘json’

printSchema
JSONData.printSchema(pretty=True, **kargs)[source]

Prints structured schema.

Args:

pretty: Activates pretty printer for treeview, else flat.

sourcefile: Loads schema from ‘sourcefile’ into ‘source’.

default:=None

source: Prints schema within ‘source’.

default:=self.schema
Returns:
When successful returns ‘True’, else returns either ‘False’, or raises an exception.
Raises:

JSONDataAmbiguity:

forwarded from ‘json’

pop
JSONData.pop(key)[source]

Transparently passes the ‘pop()’ call to ‘self.data’.

setSchema
JSONData.setSchema(schemafile=None, targetnode=None, **kargs)[source]

Sets schema or inserts a new branch into the current assigned schema.

The main schema(targetnode==None) is the schema related to the current instance. Additional branches could be added by importing the specific schema definitions into the main schema. These could either kept volatile as a temporary runtime extension, or stored into a new schema file in order as extension of the original for later combined reuse.

Args:
schemafile:
JSON-Schema filename for validation of the subtree/branch. See also **kargs[‘schema’].
targetnode:
Target container hook for the inclusion of the loaded branch.
**kargs:
schema:

In-memory JSON-Schema as an alternative to schemafile. When provided the ‘schemafile’ is ignored.

default:=None

validator: [default, draft3, off, ]

Sets schema validator for the data file. The values are: default=validate, draft3=Draft3Validator, off=None.

default:= validate

persistent:

Stores the ‘schema’ persistently into ‘schemafile’ after completion of update including addition of branches. Requires valid ‘schemafile’.

default:=False

Returns:
When successful returns ‘True’, else returns either ‘False’, or raises an exception.

Raises:

JSONData:

JSONDataSourceFile:

JSONDataValue:

validate
JSONData.validate(data, schema, validator=None)[source]

Validate data with schema by selected validator.

Args:
data:
JSON-Data.
schema:
JSON-Schema for validation.
validator:

Validator to be applied, current supported:

schema:

In-memory JSON-Schema as an alternative to schemafile. When provided the ‘schemafile’ is ignored.

default:=None

validator: [default, draft3, draft4, off, on, ]
default|MODE_SCHEMA_ON
The current default.
draft3|MODE_SCHEMA_DRAFT3
The first supported JSONSchema IETF-Draft.
draft4|MODE_SCHEMA_DRAFT4
The current supported JSONSchema IETF-Draft.
off|MODE_SCHEMA_OFF:
No validation.

Sets schema validator for the data file.

default:= MODE_SCHEMA_DRAFT4

Returns:
When successful returns ‘True’, else returns either ‘False’, or raises an exception.
Raises:
ValidationError: SchemaError: JSONDataValue:

Operators

‘+’
JSONData.__add__(x)[source]

Adds the structure ‘x’ to ‘self’, performs deep-operation.

‘&&’
JSONData.__and__()[source]

Gets the intersection of ‘x’ and ‘self’, performs deep-operation.

‘()’
JSONData.__call__(x)[source]

Evaluates the pointed value from the document.

Args:
x: A valid JSONPointer.
Returns:
The pointed value, or None.
Raises:
JSONPointerException
‘S==x’
JSONData.__eq__(x)[source]

Compares this JSONData.data with x.

Args:
x: A valid JSONData.
Returns:
True or False
Raises:
JSONDataException
‘[]’
JSONData.__getitem__(key)[source]

Support of slices, for ‘iterator’ refer to self.__iter__.

‘S!=x’
JSONData.__ne__(x)[source]

Compares this JSONData with x.

Args:
x: A valid JSONData.
Returns:
True or False
Raises:
JSONDataException
‘+=’
JSONData.__iadd__(x)[source]

Adds the structure ‘x’ to ‘self’, performs deep-operation.

‘=&&’
JSONData.__iand__()[source]

Gets the intersection of ‘x’ and ‘self’, performs deep-operation.

‘S%x’
JSONData.__imod__(x)[source]

Returns the difference-modulo-set.

*=’
JSONData.__imul__(x)[source]

Duplicates the elements of ‘self’ ‘x’ times.

‘||=’
JSONData.__ior__(x)[source]

Returns the superset of branches and attributes.

‘-=’
JSONData.__isub__(x)[source]

Returns the residue of X after each present element of ‘x’ is removed.

‘^=’
JSONData.__ixor__(x)[source]

Returns the elements present in one only.

‘%’
JSONData.__mod__(x)[source]

Returns the difference-modulo-set.

The operations:

z = S % x

Returns the remaining subset of:

z = S - n * x

where ‘n*x’ is the maximum number of present branches ‘x’. When multiple exist, all matching are removed.

‘*’
JSONData.__mul__(x)[source]

Duplicates the elements of ‘self’ ‘x’ times.

The operations:

z = S * x

Returns the remaining subset of:

z = S - 1 * x

where ‘1*x’ is for each present element of ‘x’. When multiple exist ‘n-1’ remain.

‘||’
JSONData.__or__(x)[source]

Returns the superset of branches and attributes.

‘S+x’
JSONData.__radd__(x)[source]

Adds the structure ‘x’ to ‘self’, performs deep-operation.

‘S&&x’
JSONData.__rand__()[source]

Gets the intersection of ‘x’ and ‘self’, performs deep-operation.

‘S%x’
JSONData.__rmod__(x)[source]

Returns the difference-modulo-set.

‘S*x”
JSONData.__rmul__(x)[source]

Duplicates the elements of ‘self’ ‘x’ times.

‘S||x”
JSONData.__ror__(x)[source]

Returns the superset of branches and attributes.

‘S^x”
JSONData.__rxor__(x)[source]

Returns the elements present in one only.

‘-‘
JSONData.__sub__(x)[source]

Returns the residue of X after each present element of ‘x’ is removed.

The operations:

z = S - x

Returns the remaining subset of:

z = S - 1 * x

where ‘1*x’ is for each present element of ‘x’. When multiple exist ‘n-1’ remain.

‘^’
JSONData.__xor__()[source]

Returns the structure elements present in in one only.

Iterators

__iter__
JSONData.__iter__()[source]

Provides an iterator for data.

Exceptions

class jsondata.JSONData.JSONDataAmbiguity(requested, *sources)[source]

Error ambiguity of provided parameters.

‘jsondata.JSONDataSerializer’ - Module

Basic features for the persistence of JSON based in-memory data.

JSONDataSerializer

class jsondata.JSONDataSerializer.JSONDataSerializer(appname, *args, **kargs)[source]

Persistency of JSON based data for the class jsondata.JSONData.

This class provides for persistency of data managed by jsondata.JSONData.

Attributes:
data: The data tree of JSON based objects provided
by the module ‘json’.
schema: The validator for ‘data’ provided by
the module ‘jsonschema’.
Common call parameters provided by the methods of this class are:
targetnode := addressreference
The target node of called method. The ‘targetnode’ in general represents the target of the called method. In most cases this has to be a reference to a container for the modification and/or insertion of resulting elements. The methods require the change of contained items, which involves the application of a ‘key’ pointing to the hook in point of the reference to the modification.
key := key-value
The hook-in point for references of modified entries within the targetnode container. The following values are supported:
sourcenode := addressreference
The in-memory node address of the source branch for the method, e.g. ‘copy’ or ‘move’ operation.

The address references supported in this class refer the resulting in-memory representation of a pointer path. The target is a node within a Python data representation as provided by the package ‘json‘ and compatible packages, e.g. ‘ujson‘. The supported input syntax is one of the following interchangeable formats:

# The reference to a in-memory-node.
addressreference := (
      nodereference
    | addressreference-source
)

nodereference:= (
      <in-memory>
    | ''
)

<in-memory> := "Memory representation of a JSON node, a 'dict'
    or a 'list'. The in-memory Python node reference has to be
    located within the document, due to performance reasons this
    is not verified by default.
    
    The 'nodereference' could be converted from the
    'addressreference-source' representation."

'' := "Represents the whole document in accordance to RFC6901.
    Same as 'self.data'." 

# The source of the syntax for the description of the reference
# pointer path to a node. This is applicable on paths to be created.
addressreference-source := (
    JSONPointer
)
      
JSONPointer:="A JSONPointer object in accordance to RFC6901.
    for additional information on input formats refer to the 
    class documentation.
    This class provides a fully qualified path pointer, which
    could be converted into any of the required representations."

For hooks by ‘key-value’ within addressed containers:

key-value:=(None|<list-index>|<dict-key>) 
    
None := "When the 'key' parameter is 'None', the action 
    optionally could be based on the keys of the 'sourcenode'.  
    The contents of the branch replace the node contents
    when the type of the branch matches the hook."

<list-index>:=('-'|int)

<dict-key>:="Valid for a 'dict' only, sets key/value pair, 
    where present is replace, new is created."

'-' := "Valid for a 'list' only, appends to present."

int := "Valid for a 'list' only, replaces present when
    0 < #int < len(Node)."

In the parameter lists of methods used term ‘pointer’ is either an object of class ‘JSONPointer’, or a list of pointer path entries.

The JSON types ‘object’ and ‘array’ behave in Python slightly different in accordance to RFC6902. The main difference arise from the restrictions on applicable key values. Whereas the ranges are limited logically by the actual container sizes, the object types provide free and unlimited keys. The limit is set by type restriction to unicode and ‘non-nil’ only for keys.

Attributes

  • JSONDataSerializer.data: JSON object data tree.
  • JSONDataSerializer.schema: JSONschema object data tree.

Methods

__init__
JSONDataSerializer.__init__(appname, *args, **kargs)[source]

Loads and validates a JSON definition with the corresponding schema file.

Args:
appname: Name of the application. An arbitrary string representing the
name of an application. The name is mainly used for the default name prefix of the JSON data and schema.
args*: Optional position parameters, these branch_replace corresponding key
parameters. filelist, pathlist, filepathlist, schemafile
**kargs:
datafile: Filepathname of JSON data file, when provided a further

search by pathlist, filelist, and filepathlist is suppressed. Therefore it has to be a valid filepathname.

default:= <appname>.json

filelist: List of valid filenames.

default:= <appname>.json
filepathlist: List of filepathnames. These are not prefixed by search

path components, but made absolute.

default:= []

filepriority: [firstonly, lastonly, all]

Defines the handling of multiple occurrences of a filename at varios positions. This option thus may only be altered in conjunction with ‘pathlist’.

default:= all

indent_str: Defied the indentation of ‘str’.

default:= 4

interactive: Hints on command line call for optional change of display format.

default:= False
loadcached: Caching of load for JSON data files.

Loads either completely into cache before transferring to production entries, or immediately into production parameters, which may take an effect on the remaining parameters to be loaded.

default:= False

nodefaultpath: Ignores the default paths, the exception is the

base configuration, which still is searched within the default paths exclusively.

default:= False

nosubdata: Supresses the load of sub-data files.
default:= False
pathlist: List of pathnames for search of a valid filename.

Either a PATH like string, or a list of single paths.

default:= ../dirname(__file__)/etc/:dirname(__file__)/:/etc/:$HOME/etc/

requires: [all, base, one]

Defines how to handle missing or invalid files.

default:= all

schema: A valid in-meory JSONschema.

default:= None

schemafile: Filepathname of JSONschema file.

default:= <appname>.jsd
validator: [default, draft3, off, ]

Sets schema validator for the data file. The values are: default=validate, draft3=Draft3Validator, off=None

default:= validate

printdata: branch=None

Pretty print resulting final data of branch.

default:= top

printschema: branch=None

Pretty print resulting schema.

default:= top

debug: Displays extended state data for developers.
Requires __debug__==True.
verbose: Extends the amount of the display of
processing data.
Returns:
Results in an initialized object.
Raises:

NameError:

JSONDataSourceFile:

JSONDataAmbiguity:

JSONDataValue:

jsonschema.ValidationError:

jsonschema.SchemaError:

__str__
JSONDataSerializer.__str__()

Dumps data by pretty print.

__repr__
JSONDataSerializer.__repr__()

Dump data.

json_export
JSONDataSerializer.json_export(sourcenode, fname, **kargs)[source]

Exports current data for later import.

The exported data is a snapshot of current state.

Args:

fname: File name for the exported data.

sourcenode: Base of sub-tree for export.
None for complete JSON document.
**kargs:
ffs.
Returns:
When successful returns ‘True’, else returns either ‘False’, or raises an exception.
Raises:
JSONDataTargetFile:
json_import
JSONDataSerializer.json_import(targetnode, key, datafile, schemafile=None, **kargs)[source]

Imports and validates JSON based data.

The contained data in ‘datafile’ could be either the initial data tree, or a new branch defined by a fresh tree structure. The ‘targetnode’ defines the parent container where the new branch has to be hooked-in.

Args:
targetnode:
Target container for the inclusion of the loaded branch. For the default:=’None’ the ‘self.data’ is used.
key:
The hook within the targetnode,
datafile:
JSON data filename containing the subtree for the target branch.
schemafile:
JSON-Schema filename for validation of the subtree/branch.
**kargs:
matchcondition:

Defines the criteria for comparison of present child nodes in the target container. The value is a list of criteria combined by logical AND. The criteria may vary due to the requirement and the type of applied container.

For information on applicable values refer to:
‘JSONDataSerializer.isApplicable()’
validator: [default, draft3, off, ]

Sets schema validator for the data file. The values are: default=validate, draft3=Draft3Validator, off=None.

default:= validate

Returns:
When successful returns ‘True’, else returns either ‘False’, or raises an exception.
Raises:

JSONData:

JSONDataValue:

JSONDataSourceFile:

printData
JSONDataSerializer.printData(pretty=True, **kargs)[source]

Prints structured data.

Args:

pretty: Activates pretty printer for treeview, else flat.

sourcefile: Loads data from ‘sourcefile’ into ‘source’.

default:=None

source: Prints data within ‘source’.

default:=self.data
Returns:
When successful returns ‘True’, else returns either ‘False’, or raises an exception.
Raises:

JSONDataAmbiguity:

forwarded from ‘json’

printSchema
JSONDataSerializer.printSchema(pretty=True, **kargs)[source]

Prints structured schema.

Args:

pretty: Activates pretty printer for treeview, else flat.

sourcefile: Loads schema from ‘sourcefile’ into ‘source’.

default:=None

source: Prints schema within ‘source’.

default:=self.schema
Returns:
When successful returns ‘True’, else returns either ‘False’, or raises an exception.
Raises:

JSONDataAmbiguity:

forwarded from ‘json’

setSchema
JSONDataSerializer.setSchema(schemafile=None, targetnode=None, **kargs)[source]

Sets schema or inserts a new branch into the current assigned schema.

The main schema(targetnode==None) is the schema related to the current instance. Additional branches could be added by importing the specific schema definitions into the main schema. These could either kept volatile as a temporary runtime extension, or stored into a new schema file in order as extension of the original for later combined reuse.

Args:
schemafile:
JSON-Schema filename for validation of the subtree/branch. See also **kargs[‘schema’].
targetnode:
Target container hook for the inclusion of the loaded branch.
**kargs:
schema:

In-memory JSON-Schema as an alternative to schemafile. When provided the ‘schemafile’ is ignored.

default:=None

validator: [default, draft3, off, ]

Sets schema validator for the data file. The values are: default=validate, draft3=Draft3Validator, off=None.

default:= validate

persistent:

Stores the ‘schema’ persistently into ‘schemafile’ after completion of update including addition of branches. Requires valid ‘schemafile’.

default:=False

Returns:
When successful returns ‘True’, else returns either ‘False’, or raises an exception.

Raises:

JSONData:

JSONDataSourceFile:

JSONDataValue:

‘jsondata.JSONPointer’ - Module

Provides classes for the JSONPointer definition in accordance to RFC6901.

The provided class JSONPointer internally stores and applies pointer data as a list of keys and indexes with the additional cooperative caching of the pointed in-memory node reference for fast access on data provided by the packages ‘json’ and ‘jsonschema’. Requests for the string representation are transformed into a pointer path in accordance to RFC6901.

The JSONPointer class combines fast in-memory operations and pointer arithmetics with standards compliant path strings at the API.

The JSONPointer class by itself is focused on the path pointer itself, though the provided operations do not touch the content value. The pointer provides the hook where the value has to be inserted.

JSONPointer

class jsondata.JSONPointer.JSONPointer(ptr, replace=True, **kargs)[source]

Represents exactly one JSONPointer in compliance with IETF RFC6901. This pointer could be processed by extension, reduction, and general modification with support of provided methods and path arithmetic operators.

The JSONPointer is provided at the API as a utf(-8) string in accordance to RFC6901, including RFC3869.

For enhancement of the processing performance by the underlying packages ‘json’ and ‘jsonschema’, the pointer is stored and applied in two variants.

  • self.raw: Raw input of the pointer string for the logical API.

  • self.ptr: Split elements of the pointer path within a list of keys,

    for the programming interface.

The attribute ‘self.ptr’ contains the path elements in a ‘list’:

ptrlist := (<EMPTY>|plist)
<EMPTY> := "empty list, represents the whole document"
plist := pkey [, plist ]
pkey := (''|int|keyname)
'' := "the empty string is a valid key too"
int := "integer index of an array item, just digits"
keyname := "the valid name of an object/property entry" 

The JSONPointer:

"/address/0/streetName"

is represented as:

['address', 0, 'streetName' ]

The methods and operators are handling the pointer itself, the values referenced by the pointer are not modified.

The methods of this class support for multiple input format of the JSONPointer. The parameter ‘x’ in the operations is defined as a valid JSONPointer fragment. A pointer fragment is a part of a pointer, which could be the complete pointer itself - the all-fragment.

The syntax element could be one of:

'str': A string i accordance to RFC6901. Strings are represented 
    internally as unicode utf-8.
    
    Here either the input parameter 'x' is split into
    a list, or in case of combining operations, the self.ptr
    attribute is 'joined' to be used for the method. 

'int': A numeric value in case of an array index. This value 
    is internally handled for the string representation as a
    unicode utf-8, whereas for the addressing of memory 
    objects the numeric integer value is stored and applied.

'JSONPointer': The attributes of the input object are used 
    with it's peers.

'list': Expects a path list containing:
    - JSON object names
        Names of the json objects.
    - array indexes
        Numeric index for arrays.
    - JSONPointer
        A JSONPointer object, the path is resolved as a section 
        of overall path.

    The self.ptr attribute is applied for operations.

The node reference is cached by the ‘get_node’ and ‘get_node_or_value’ method, thus could be accessed by ‘self.node’, but is not monitored to be valid. Another call of the method reloads the cache by evaluating the pointer value on the document again.

The provided value is internally stored as a raw input value, and a list of keys and indexes for access to in-memory data as provided by the packages ‘json’ and ‘jsonschema’. Requests for the string representation are transformed into a pointer path in accordance to RFC6901. This provides for fast access in case of pointer arithmetics, while providing standards conform path strings at the interface.

Attributes

JSONPointer:

  • JSONPointer.ptr: JSONPointer data.
  • JSONPointer.raw: Raw input string for JSONPointer.

Methods

__init__
JSONPointer.__init__(ptr, replace=True, **kargs)[source]

Converts and stores a JSONPointer as a list.

Processes the ABNF of a JSON Pointer from RFC6901.

Args:
ptr: A JSONPointer to be represented by this object. The
supported formats are:

‘str’: A string i accordance to RFC6901 JSONPointer: A valid object, will be copied

into this, see ‘deep’.
‘list’: expects a path list, where each item
is processed for escape and unquote.

replace: Replaces masked characters. **kargs:

deep: Applies for copy operations on structured data
‘deep’ when ‘True’, else ‘swallow’ only, which is just a link to the data structure. Flat data types are copied by value in any case.

node: Force to set the pointed node in the internal cache. debug: Enable debugging.

Returns:
When successful returns ‘True’, else returns either ‘False’, or raises an exception. Success is the complete addition only, thus one failure returns False.
Raises:
JSONPointerException:
__repr__
JSONPointer.__repr__()[source]

Returns the attribute self.raw, which is the raw input JSONPointer.

__str__
JSONPointer.__str__()[source]

Returns the string for the processed path.

check_node_or_value
JSONPointer.check_node_or_value(jsondata, parent=False)[source]

Checks the existance of the corresponding node within the JSON document.

Args:
jsondata: A valid JSON data node. parent: Return the parent node of the pointed value.
Returns:
True or False
Raises:
JSONPointerException: forwarded from json
copy_path_list
JSONPointer.copy_path_list(parent=False)[source]

Returns a deep copy of the objects pointer path list.

Args:
parent: The parent node of the pointer path.
Returns:
A copy of the path list.
Raises:
none
get_node
JSONPointer.get_node(jsondata, parent=False)[source]

Gets the corresponding node reference for a JSON container type.

This method gets nodes of container types. Container types of JSON are ‘array’ a.k.a. in Python ‘list’, and ‘objects’ a.k.a. in Python ‘dict’.

Due to the special case of RFC6902 ‘append’ by the array index ‘-‘ in combination of the add rules a special exception-treatment is required, for details refer to RFC6902.

The ‘get_node’ method therefore returns only an existing node of a of valid non-ambiguous path pointer. This excludes pointers containing the symbolic index ‘-‘ for an array component.

See also related methods:

get_node_and_child: For Python access to a child node
within a container by the container itself, and the item key.
get_node_exist: For the application of partial valid
pointer paths of new branches.
get_node_or_value: For any type of pointed item, either
a node, or a value.
Args:

jsondata: A valid JSON data node. parent: Return the parent node of the pointed value.

When parent is selected, the pointed child node is not verified.
Returns:
The node reference.
Raises:
JSONPointerException: forwarded from json
get_node_and_child
JSONPointer.get_node_and_child(jsondata)[source]

Returns a tuple containing the parent node and the child.

Args:
jsondata: A valid JSON data node.
Returns:

The the tuple: (n,c): n: Node reference to parent container.

c: Key for the child entry, either an
index ‘int’, or a key (‘str’, ‘unicode’).
Raises:
JSONPointerException: forwarded from json
get_node_exist
JSONPointer.get_node_exist(jsondata, parent=False)[source]

Returns the node for valid part of the pointer, and the remaining part.

This method works similar to the ‘get_node’ method, whereas it handles partial valid path pointers, which may also include a ‘-‘ in accordance to RFC6902.

Therefore the non-ambiguous part of the pointer is resolved, and returned with the remaining part for a newly create. Thus this method is in particular foreseen to support the creation of new sub data structures.

The ‘get_node’ method therefore returns a list of two elements, the first is the node reference, the second the list of the remaining path pointer components. The latter may be empty in case of a fully valid pointer.

Args:
jsondata: A valid JSON data node. parent: Return the parent node of the pointed value.
Returns:
The node reference, and the remaining part. ret:=[ node, [<remaining-path-components-list>] ]
Raises:
JSONPointerException: forwarded from json
get_node_or_value
JSONPointer.get_node_or_value(jsondata, valtype=None, parent=False)[source]

Gets the corresponding node reference or the JSON value of a leaf.

Relies on the standard package ‘json’ by ‘Bob Ippolito <bob@redivi.com>’. This package supports in the current version the following types:

JSON Python
object dict
array list
string unicode
number (int) int, long
number (real) float
true True
false False
null None

It also understands NaN, Infinity, and -Infinity as their corresponding float values, which is outside the JSON spec.

The supported standard value types for Python of get_node_or_value() are mapped automatically as depicted in the following table. Additional bindings may be implemented by sub-classing.

JSONPointer(jsondata) Python-valtype
object (dict) dict
array (list) list
array (tuple) list
string unicode
number (int) int
number (long) long
number (float) float
*number (double) float
number (octal) int
number (hex) int
number (binary) int
number (complex)
  • (custom)
true True
false False
null None

The mappings in detail are:

  • object(dict) => dict:

    {a:b} - native Python dictionary

  • array(list) => list:

    [a,b] - native Python list

  • (*)array(tuple) => list:

    (a,b) - native Python list

  • string(str) => unicode”

    “abc” - native Python unicode string UTF-8

  • number(int) => int:

    1234, −24, 0 - Integers (unlimited precision)

  • number(long) => int:

    1234, −24, 0 - Integers (unlimited precision)

  • number(float) => float:

    1.23, 3.14e-10, 4E210, 4.0e+210, 1., .1 - Floating-point (normally implemented as C doubles in CPython)

  • (*)number(double) => float:

    1.23, 3.14e-10, 4E210, 4.0e+210, 1., .1 - Floating-point (normally implemented as C doubles in CPython)

  • number(octal) => int:

    0o177 - Octal, hex, and binary literals for integers2

  • number(hex) => int:

    0x9ff - Octal, hex, and binary literals for integers2

  • number(binary) => int:

    0b1111 - Octal, hex, and binary literals for integers2

  • number(complex) => <not-supported>(requires custom):

    3+4j, 3.0+4.0j, 3J - Complex numbers

  • true(True) => boolean(True):

    True - native Python boolean

  • false(False) => boolean(False):

    False - native Python boolean

  • null(None) => NoneType(None):

    False - native Python NoneType

Args:
jsondata: A valid JSON data node. valtype: Type of requested value. parent: Return the parent node of the pointed value.
Returns:
The node reference.
Raises:
JSONPointerException: forwarded from json
get_path_list
JSONPointer.get_path_list()[source]

Gets for the corresponding path list of the object pointer for in-memory access on the data of the ‘json’ package.

Args:
none
Returns:
The path list.
Raises:
none
get_path_list_and_key
JSONPointer.get_path_list_and_key()[source]

Gets for the corresponding path list of the object pointer for in-memory access on the data of the ‘json’ package.

Args:
none
Returns:
The path list.
Raises:
none
get_pointer
JSONPointer.get_pointer(forcenotation=None, parent=False)[source]

Gets the objects pointer in compliance to RFC6901.

Args:
forcenotation: Force the output notation to:
None := NOTATION_JSON, NOTATION_JSON = 0, NOTATION_HTTP_FRAGMENT = 1

parent: Get parent of selected node.

Returns:
The pointer in accordance to RFC6901.
Raises:
none
get_raw
JSONPointer.get_raw()[source]

Gets the objects raw 6901-pointer.

Args:
none
Returns:
The raw path.
Raises:
none

Operators

The syntax displayed for provided operators is:

S: self
x: parameter
n: numerical parameter for shift operators.

Thus the position of the opreator and parameteres is defined as follows:

z = S + x: LHS: __add__
z = x + S: RHS: __radd__
S += x:    LHS: __iadd__
‘S+x’
JSONPointer.__add__(x)[source]

Appends a Pointer to self.

Args:
x: A valid JSONPointer fragment.
Returns:
A new object of JSONPointer
Raises:
JSONPointerException:
‘S(x)’
JSONPointer.__call__(x)[source]

Evaluates the pointed value from the document.

Args:
x: A valid JSON document.
Returns:
The pointed value, or None.
Raises:
JSONPointerException
‘S==x’
JSONPointer.__eq__(x)[source]

Compares this pointer with x.

Args:
x: A valid Pointer.
Returns:
True or False
Raises:
JSONPointerException
‘S>=x’
JSONPointer.__ge__(x)[source]

Checks containment(>=) of another pointer within this.

The weight of contained entries is the criteria, though the shorter is the bigger. This is true only in case of a containment relation.

The number of equal path pointer items is compared.

Args:
x: A valid Pointer.
Returns:
True or False
Raises:
JSONPointerException:
‘S>x’
JSONPointer.__gt__(x)[source]

Checks containment(>) of another pointer or object within this.

The number of equal items is compared.

Args:
x: A valid Pointer.
Returns:
True or False
Raises:
JSONPointerException:
‘S+=x’
JSONPointer.__iadd__(x)[source]

Add in place x to self, appends a path.

Args:
x: A valid Pointer.
Returns:
‘self’ with updated pointer attributes
Raises:
JSONPointerException:
‘S<x’
JSONPointer.__le__(x)[source]

Checks containment(<=) of this pointer within another.

The number of equal items is compared.

Args:
x: A valid Pointer.
Returns:
True or False
Raises:
JSONPointerException:
‘S<x’
JSONPointer.__lt__(x)[source]

Checks containment(<) of this pointer within another.

The number of equal items is compared.

Args:
x: A valid Pointer.
Returns:
True or False
Raises:
JSONPointerException:
‘S!=x’
JSONPointer.__ne__(x)[source]

Compares this pointer with x.

Args:
x: A valid Pointer.
Returns:
True or False
Raises:
JSONPointerException
‘x+S’
JSONPointer.__radd__(x)[source]

Adds itself as the right-side-argument to the left.

This method appends ‘self’ to a path fragment on the left. Therefore it adds the path separator on it’s left side only. The left side path fragment has to maintain to be in accordance to RFC6901 by itself.

Once ‘self’ is added to the left side, it terminates it’s life cycle. Thus another simultaneous add operation is handled by the resulting other element.

Args:
x: A valid Pointer.
Returns:
The updated input of type ‘x’ as ‘x+S(x)’
Raises:
JSONPointerException:

Iterators

iter_path
JSONPointer.iter_path(jsondata=None, parent=False, rev=False)[source]

Iterator for the elements of the path pointer itself.

Args:
jsondata: If provided a valid JSON data node, the
path components are successively verified on the provided document. If None the path pointer components are just iterated.

parent: Uses the path pointer to parent node. rev: Reverse the order, start with last.

Returns:
Yields the iterator for the current path pointer component.
Raises:
JSONPointerException: forwarded from json
iter_path_nodes
JSONPointer.iter_path_nodes(jsondata, parent=False, rev=False)[source]

Iterator for the elements the path pointer points to.

Args:
jsondata: A valid JSON data node. parent: Uses the path pointer to parent node. rev: Reverse the order, start with last.
Returns:
Yields the iterator of the current node reference.
Raises:
JSONPointerException: forwarded from json

‘jsondata.JSONPatch’ - Module

The JSONPatch module provides for the alteration of JSON data compliant to RFC6902.

The emphasis of the design combines low resource requirement with features designed for the application of large filters onto large JSON based data structures.

The patch list itself is defined by RFC6902 as a JSON array. The entries could be either constructed in-memory, or imported from a persistent storage. The export feature provides for the persistent storage of a modified patch list for later reuse.

The module contains the following classes:

  • JSONPatch:

    The controller for the application of patches on in-memory data structures provided by the package ‘json’.

  • JSONPatchItem:

    Representation of one patch entry in accordance to RFC6902.

  • JSONPatchItemRaw:

    Representation of one patch entry read as a raw entry in accordance to RFC6902.

  • JSONPatchFilter:

    Selection filter for the application on the current patch list entries JSONPatchItem.

  • JSONPatchException:

    Specific exception for this module.

The address of the the provided ‘path’ components for the entries are managed by the class JSONPointer in accordance to RFC6901.

Functions

getOp

jsondata.JSONPatch.getOp(x)[source]

Converts input into corresponding enumeration.

JSONPatch

class jsondata.JSONPatch.JSONPatch[source]

Representation of a JSONPatch task list for RFC6902.

Contains the defined methods from standards:

  • add
  • remove
  • replace
  • move
  • copy
  • test
Attributes:
patch: List of patch items.

Attributes

  • JSONPatch.data: JSONPatch object data tree.

Methods

__init__
JSONPatch.__init__()[source]
__str__
JSONPatch.__str__()[source]

Prints the display format.

__repr__
JSONPatch.__repr__()[source]

Prints the representation format of a JSON patch list.

apply
JSONPatch.apply(jsondata)[source]

Applies the JSONPatch task.

Args:
jsondata: JSON data the joblist has to be applied on.
Returns:
Returns a tuple of:
0: len of the job list 1: list of the execution status for the tasks
Raises:
JSONPatchException:
get
JSONPatch.get(x=None)[source]
patch_export
JSONPatch.patch_export(patchfile, schema=None, **kargs)[source]

Exports the current task list.

Provided formats are:
RFC6902
Supports the formats:
RFC6902
Args:
patchfile:
JSON patch for export.
schema:
JSON-Schema for validation of the patch list.
**kargs:
validator: [default, draft3, off, ]
Sets schema validator for the data file. The values are: default=validate, draft3=Draft3Validator, off=None. default:= validate
Returns:
When successful returns ‘True’, else raises an exception.
Raises:
JSONPatchException:
patch_import
JSONPatch.patch_import(patchfile, schemafile=None, **kargs)[source]

Imports a task list.

Supports the formats:
RFC6902
Args:
patchfile:
JSON patch filename containing the list of patch operations.
schemafile:
JSON-Schema filename for validation of the patch list.
**kargs:
validator: [default, draft3, off, ]
Sets schema validator for the data file. The values are: default=validate, draft3=Draft3Validator, off=None. default:= validate
Returns:
When successful returns ‘True’, else raises an exception.
Raises:
JSONPatchException:
repr_export
JSONPatch.repr_export()[source]

Prints the export representation format of a JSON patch list.

Operators

‘()’
JSONPatch.__call__(j, x=None)[source]

Evaluates the related task for the provided index.

Args:

x: Task index.

j: JSON data the task has to be
applied on.
Returns:
Returns a tuple of:

0: len of the job list 1: list of the execution status for

the tasks
Raises:
JSONPatchException:
‘[]’
JSONPatch.__getitem__(key)[source]

Support of slices, for ‘iterator’ refer to self.__iter__.

  1. self[key]
  2. self[i:j:k]
  3. x in self
  4. for x in self
‘S+x’
JSONPatch.__add__(x=None)[source]

Creates a copy of ‘self’ and adds a patch jobs to the task queue.

‘S==x’
JSONPatch.__eq__(x)[source]

Compares this pointer with x.

Args:
x: A valid Pointer.
Returns:
True or False
Raises:
JSONPointerException
‘S+=x’
JSONPatch.__iadd__(x=None)[source]

Adds patch jobs to the task queue in place.

‘S-=x’
JSONPatch.__isub__(x)[source]

Removes the patch job from the task queue in place.

Removes one of the following type(x) variants:

int: The patch job with given index.

JSONPatchItem: The first matching entry from
the task queue.
Args:
x: Item to be removed.
Returns:
Returns resulting list without x.
Raises:
JSONPatchException:
‘S!=x’
JSONPatch.__ne__(x)[source]

Compares this pointer with x.

Args:
x: A valid Pointer.
Returns:
True or False
Raises:
JSONPointerException
‘S-x’
JSONPatch.__sub__(x)[source]

Removes the patch job from the task queue.

Removes one of the following type(x) variants:

int: The patch job with given index.

JSONPatchItem: The first matching entry from
the task queue.
Args:
x: Item to be removed.
Returns:
Returns resulting list without x.
Raises:
JSONPatchException:
len
JSONPatch.__len__()[source]

The number of outstanding patches.

Iterators

__iter__
JSONPatch.__iter__()[source]

Provides an iterator foreseen for large amounts of in-memory patches.

JSONPatchItem

class jsondata.JSONPatch.JSONPatchItem(op, target, param=None)[source]

Record entry for list of patch tasks.

Attributes:
op: operations:
add, copy, move, remove, replace, test

target: JSONPointer for the modification target, see RFC6902.

value: Value, either a branch, or a leaf of the JSON data structure. src: JSONPointer for the modification source, see RFC6902.

Methods

__init__
JSONPatchItem.__init__(op, target, param=None)[source]

Create an entry for the patch list.

Args:

op: Operation: add, copy, move, remove, replace, test

target: Target node.

param: Parameter specific for the operation:
value: add,replace, test src: copy, move param:=None for ‘remove’
Returns:
When successful returns ‘True’, else returns either ‘False’, or raises an exception. Success is the complete addition only, thus one failure returns False.
Raises:
JSONDataSerializerError:
__repr__
JSONPatchItem.__repr__()[source]

Prints the patch string in accordance to RFC6901.

__str__
JSONPatchItem.__str__()[source]

Prints the patch string in accordance to RFC6901.

apply
JSONPatchItem.apply(jsondata)[source]

Applies the present patch list on the provided JSON document.

Args:
jsondata: Document to be patched.
Returns:

When successful returns ‘True’, else raises an exception. Or returns a tuple:

(n,lerr): n: number of present active entries
lerr: list of failed entries
Raises:
JSONPatchException:
repr_export
JSONPatchItem.repr_export()[source]

Prints the patch string for export in accordance to RFC6901.

Operators

‘()’
JSONPatchItem.__call__(j)[source]

Evaluates the related task for the provided data.

Args:
j: JSON data the task has to be
applied on.
Returns:
Returns a tuple of:

0: len of the job list 1: list of the execution status for

the tasks
Raises:
JSONPatchException:
‘[]’
JSONPatchItem.__getitem__(key)[source]

Support of various mappings.

  1. self[key]
  2. self[i:j:k]
  3. x in self
  4. for x in self
‘S==x’
JSONPatchItem.__eq__(x)[source]

Compares this pointer with x.

Args:
x: A valid Pointer.
Returns:
True or False
Raises:
JSONPointerException
‘S!=x’
JSONPatchItem.__ne__(x)[source]

Compares this pointer with x.

Args:
x: A valid Pointer.
Returns:
True or False
Raises:
JSONPointerException

JSONPatchItemRaw

class jsondata.JSONPatch.JSONPatchItemRaw(patchstring)[source]

Adds native patch strings or an unsorted dict for RFC6902.

Methods

__init__
JSONPatchItemRaw.__init__(patchstring)[source]

Parse a raw patch string in accordance to RFC6902.

Class: JSONPatchFilter

class jsondata.JSONPatch.JSONPatchFilter(**kargs)[source]

Filtering capabilities on the entries of patch lists.

Methods

__init__
JSONPatchFilter.__init__(**kargs)[source]
Args:
**kargs: Filter parameters:

Common:

contain=(True|False): Contain, else equal.

type=<node-type>: Node is of type.

Paths:

branch=<branch>:

deep=(): Determines the depth of comparison.

prefix=<prefix>: Any node of prefix. If prefix is
absolute: the only and one, else None. relative: any node prefixed by the path fragment.
Values:
val=<node-value>: Node ha the value.
Returns:
True or False
Raises:
JSONPointerException:

Operators

‘==’
JSONPatchFilter.__eq__(x)[source]
‘!=’
JSONPatchFilter.__ne__(x)[source]

‘jsondata.JSONTree’ - Module

The JSONTree module provides features for in-memory JSON structures.

The provided features comprise:

  • The construction and printout of tree formatted structures for screen analysis.
  • Comparison of JSON strings as tree structures.

Constants

Operations modes

  • _interactive = False: Activates interactive mode.

Diff Mode

  • DIFF_FIRST = 0: break display of diff after first
  • DIFF_ALL = 1: list all diffs

Displayed Character Set

  • CHARS_RAW = 0: display character set as raw
  • CHARS_RAW = 1: display character set as str
  • CHARS_RAW = 2: display character set as utf/utf-8

Line-Overflow

  • LINE_CUT = 0: force line fit
  • LINE_WRAP = 1: wrap line in order to fit to length

JSONTree

class jsondata.JSONTree.JSONTree(**kargs)[source]

Variables

  • self.difflist : reaulting differences
  • self.scope: scope of differences
  • self.linefit: handle overflow
  • self.linewidth: line width
  • self.charset: character set
  • self.indent: indention steps

Methods

__init__
JSONTree.__init__(**kargs)[source]

Create an object for the tree representation.

Args:

**kargs: Parameter specific for the operation,

scope:

  • all: Display all diffs.
  • first: Display first diff only.

default:=first

charset:

  • raw: Use ‘raw’.
  • str: Use ‘str’.
  • utf: Use ‘utf’.

default:=raw

debug:

Add developer information.

linefit:

  • cut: Cut lines to length.
  • wrap: Split lines to length.

default:=wrap

indent=#numchars:

Number of characters for indentation.

linewidth=#numchars:

Length of lines.

verbose:

Add progress and status dialogue output.
Returns:
When successful returns ‘True’, else raises an exception.
Raises:
passed through exceptions:
printDiff
JSONTree.printDiff()[source]

Prints out the resulting list of differences.

Args:
ffs.
Returns:
When successful returns tree represantation.
Raises:
passed through exceptions:
fetchDiff
JSONTree.fetchDiff(n0, n1, p=[], dl=0)[source]

Recursive tree compare for Python trees as used for the package ‘json’.

Finds diff in native Python trees assembled by the standard package ‘json’ and compatible, e.g. ‘ujson’.

  • leveltop
  • levelbottom
  • delta (for containers)
  • scope(all, first)
  • linewidth
  • displaycharset (str,utf)
  • pathonly

Args:

n0:

JSON string of type ‘str’, or ‘unicode’

n1:

JSON string of type ‘str’, or ‘unicode’

p=[]:

Result entries for each difference:
{'n0':n0,'n1':n1,'dl':dl,'p':p[:]}
  1. first JSON data
  2. second JSON data
  3. diff count increment value
  4. current diff including path

List of differences as of:

  1. non equal types are different: type(n0) != type(n1)

  2. equal types, both list: type(n0) is list

    1. length is different: len(n0.keys()) != len(n1.keys())
    2. at leats one item is different: n1.get(ni) and v != n1[ni]
  3. equal types, both dict: type(n0) is dict and type(n1) is dict

    1. length is different: len(n0.keys()) != len(n1.keys())
    2. at leats one item is different: n1.get(ni) and v != n1[ni]

default:=0

Returns:
When no diffs returns True, else False or raises an exception. The resulting differences are contained in the provided list parameter ‘p’. When not provided the resulting list is suppressed.
Raises:
passed through exceptions:

Exceptions

class jsondata.JSONTree.JSONTreeException[source]

Error in JSONTree.

‘jsondata.Selftest’ - Module

Test of basic features for the user by ‘–selftest’.

This module is used by ‘jsondc’ when the opverify_data_schemaardoced basic functional checks by calling ‘runselftest’.

The display of actions and results could be activated and raised by multiple repetition of the ‘-v’ option.

The following data and schema are applied:
  1. jsondata/data.json + jsondata/schema.jsd
  2. jsondata/datacheck.json + jsondata/datacheck.jsd
The performed process flow is:
  1. load
  2. validate
  3. verify

By default either ‘True’ is returned, or in case of a failed test and/or error condition an exception is raised.

Basic

  • runselftest
jsondata.Selftest.runselftest(appname='selftest', **kargs)[source]

Performs the selftest returns True or False. Executes some the basic runtime test cases for user verification.

Args:
appname: Name of the application. Changing this may break the
selftest. default:=selftest
**kargs:
debug: Displays extended state data for developers.
Requires __debug__==True.
verbose: Extends the amount of the display of
processing data.
_verbose=#levels: Extends the amount of the display
of processing data by given number of levels at once.
Returns:
Selftest object.
Raises:
bypassed subsystems
  • printverbose
jsondata.Selftest.printverbose(lvl, args)[source]

Load Tests

  • load_data
jsondata.Selftest.load_data(appname)[source]

Loads and verifies the self test ‘data.json’.

Therefore the result of the creation of JSONDataSerializer is compared to the load by json.load().

  • load_appname
jsondata.Selftest.load_appname(appname)[source]

Loads and verifies the self test ‘selftest.json’.

Therefore the result of the creation of JSONDataSerializer is compared to the load by json.load().

Validation Tests

  • verify_data_schema
jsondata.Selftest.verify_data_schema(appname)[source]

Loads and validates the self test ‘data.json’ and ‘schema.jsd’.

Therefore the result of the creation of JSONDataSerializer is performed with draft3 validation by jsonschema.validate().

  • verify_appname_schema
jsondata.Selftest.verify_appname_schema(appname)[source]

Loads and validates the self test ‘selftest.json’ and ‘selftest.jsd’.

Therefore the result of the creation of JSONDataSerializer is performed with draft3 validation by jsonschema.validate().

JSONPointer tests

  • jsonpointer_data_schema
jsondata.Selftest.jsonpointer_data_schema(appname)[source]

Loads and verifies by using JSONPointer access ‘data.json’.

  • jsonpointer_selftest_data
jsondata.Selftest.jsonpointer_selftest_data(appname)[source]

Loads and verifies by using JSONPointer access ‘selftest.json’.

  • jsonpointer_selftest_data_schema
jsondata.Selftest.jsonpointer_selftest_data_schema(appname)[source]

Loads and verifies by using JSONPointer access ‘selftest.json’.