Data Model
The datamodel module implements the following class:
DataModel
: basic user-level entry point to YANG data model information.
Doctest snippets for this module use the data model and instance document from Example 1.
- class yangson.datamodel.DataModel(yltxt: str, mod_path: List[str], description: str = None)
This class provides a basic user-level entry point to the Yangson library.
The constructor argument yltxt is a string with JSON-encoded YANG library data [RFC7895], and mod_path is a list of filesystem directories in which Yangson searches for YANG modules (by default it is only the current directory).
The description argument allows for adding a description text to the entire data model. If it is
None
, then a default description is added which contains themodule-set-id
value from the YANG library data.The class constructor may raise the following exceptions:
BadYangLibraryData
– if YANG library data is invalid.FeaturePrerequisiteError
– If a pre-requisite feature isn’t supported.MultipleImplementedRevisions
– If multiple revisions of the same module are listed in YANG library with conformance typeimplement
.ModuleNotFound
– If a YANG module specified in YANG library cannot be found in any of the directories specified in mod_path.
DataModel
is re-exported by the main package, so it can also be imported directly from there.>>> from yangson import DataModel
Instance Attributes
- schema
Root node of the schema tree.
- schema_data
Object describing various properties extracted from the data model.
- yang_library
Python dictionary containing parsed YANG library data.
Public Methods
- classmethod from_file(name: str, mod_path: List[str] = ['.'], description: str = None) DataModel
Initialize the data model from a file containing JSON-encoded YANG library data and return the
DataModel
instance. The name argument is the name of that file. The remaining two arguments are passed unchanged to theDataModel
class constructor.This method may raise the same exceptions as the class constructor.
>>> dm = DataModel.from_file("yang-library-ex1.json") >>> dm.yang_library['ietf-yang-library:modules-state']['module-set-id'] 'ae4bf1ddf85a67ab94a9ab71593cd1c78b7f231d'
- module_set_id() str
Return a unique identifier of the set of modules comprising the data model. This string, which consists of hexadecimal digits, is intended to be stored in the
module-set-id
leaf of YANG library data.The method computes the identifier as follows:
The list of module and sumodule names with revisions in the format
name@revision
is created. For (sub)modules that don’t specify any revision, the empty string is used in place ofrevision
.The list is alphabetically sorted, its entries joined back-to-back, and the result converted to a bytestring using the ASCII encoding.
The SHA-1 hash of the bytestring is computed, and its hexadecimal digest is the result.
>>> dm.module_set_id() 'ae4bf1ddf85a67ab94a9ab71593cd1c78b7f231d'
- from_raw(robj: RawObject) RootNode
Create a root instance node from a raw data tree contained in the robj argument. The latter will typically be a Python dictionary directly parsed from JSON text with the library function
json.load()
orjson.loads()
. We call this data tree “raw” because it needs to be processed into the “cooked” form before it can be used in Yangson. For example, 64-bit numbers have to be encoded as strings in JSON text (see sec. 6.1 of [RFC7951]), whereas the cooked form is a Python number.See the documentation of
instvalue
module for more details, and see also raw value.>>> with open("example-data.json") as infile: ... ri = json.load(infile) >>> inst = dm.from_raw(ri) >>> inst.value {'example-1:greeting': 'Hi!'}
- get_schema_node(path: SchemaPath) SchemaNode | None
Return the schema node addressed by path, or
None
if no such schema node exists. The path argument is a schema path.>>> root = dm.get_schema_node("/") >>> root.parent is None True
- get_data_node(path: DataPath) DataNode | None
Return the data node addressed by path, or
None
if such a data node doesn’t exist. As opposed to theget_schema_node()
method, the path argument is a data path, i.e. it contains only names of data nodes.>>> leaf = dm.get_data_node("/example-1:greeting") >>> leaf.parent is root True
- ascii_tree(no_types: bool = False, val_count: bool = False) str
Generate ASCII art representation of the actual schema tree. If no_types is set to
True
, the output of type information with leaf and leaf-list nodes is suppressed. If val_count isTrue
, each schema node is printed with the number of times it has been used for validating instances.Schema nodes are represented according to the conventions described in [RFC8340], with three differences:
Lists and leaf-lists that are ordered by user (see section 7.7.7 in [RFC7950]) are indicated by the hash symbol
#
rather than*
.Types of leaf and leaf-list nodes are enclosed in chevrons
<
and>
.Dependence on features is not indicated.
Note
ASCII trees generated by this method always depict a complete schema tree. In contrast, YANG tree diagrams defined in [RFC8340] are oriented more on partial trees of individual YANG modules.
>>> print(dm.ascii_tree(), end='') +--rw example-1:greeting? <string> >>> print(dm.ascii_tree(True), end='') +--rw example-1:greeting?
- parse_instance_id(text: str) InstanceRoute
Parse instance identifier into an internal object of the
InstanceRoute
class that can be used as a parameter to the thegoto()
andpeek()
methods of theInstanceNode
class.
- parse_resource_id(text: str) InstanceRoute
Parse resource identifier into an
InstanceRoute
object. Yangson extends the syntax of resource identifiers defined in sec. 3.5.3 of [RFC8040] so as to support entire lists and leaf-lists as resources: the last component of a resource identifier can be the name of a list or leaf-list, with no keys or value specified.
- schema_digest() str
Generate a digest of the data model schema. The digest is a streamlined and compressed JSON representation of the data model schema intended for use in restricted environments without a full YANG processing stack such as client-side applications running in a web browser.
The returned string contains a structure of JSON objects that follows the data model hierarchy. Every JSON object also contains members with information about the corresponding data node (including the anonymous root node), namely:
The following members are available for all nodes that have them:
kind
– class of the node, with these possible values:schematree
,container
,leaf
,list
,leaf-list
,anydata
andanyxml
config
–`false
if the node (and its descendants) don’t represent configurationmandatory
with the value oftrue
if the node is mandatorydescription
– description string as defined in the data model
Internal nodes (the root node, containers, and lists) have the
children
member. Its value is an object with a name/value pair for every child data node that is defined in the data model. The name is the identifier of the child identical to the name of the node’s instance – for example, it isfoomod:bar
for thebar
data node defined in thefoomod
module. The value of each member of thechildren
object is then another object containing the child’s schema digest.The following members are added for terminal nodes (leaves and leaf-lists):
type
– specifies the base type of the terminal node such asuint8
,string
, the derived type name (if any), and possibly extra information specific for the typedefault
– the default value for the node, if definedunits
- units for the node’s values, if specified
Container nodes also have the
presence
member that istrue
for containers with presence (see sec. 7.5.1 of [RFC7950]), andfalse
otherwise.List nodes also have the
keys
member whose value is an array with names of the list’s keys.
>>> len(dm.schema_digest()) 222