PyangBind

repository·master·Indexed 42 days ago

https://github.com/robshakir/pyangbind

A plugin for the pyang tool that transforms YANG data models into a structured Python class hierarchy. It enables network operators to programmatically create, load, and serialize data instances, such as OpenConfig models, providing specialized tools for XPATH resolution, extension methods, and YANG-specific metadata handling.

Tokens
16.8K
Snippets
50
Records
76
Agent score
53%

What's inside PyangBind

  1. What is PyangBind

    master

    PyangBind is a plugin for pyang that generates a Python class hierarchy from a YANG data model. These generated classes allow you to interact with YANG data directly in Python.

    Key capabilities include:

    • Creating data instances: Set values within the generated Python class hierarchy.
    • Loading data instances: Map input data from external sources to the Python classes.
    • Serializing objects: Convert populated Python objects into formats suitable for storage or transmission to network elements (e.g., via NETCONF).
  2. Explore PyangBind documentation and examples

    master

    PyangBind provides several specialized documentation areas to help you master different aspects of the library:

    Core Concepts

    • Errors: Understanding the specific exceptions thrown by PyangBind classes.
    • Generic Methods: Details on methods defined by the PyangBind meta-class and YANG-specific types like container and list.
    • Extension Methods: How to use the extmethods functionality.
    • YANG Support: An overview of how various YANG language features are mapped to PyangBind.
    • RPC: How to use PyangBind's support for the YANG rpc statement.
    • XPathHelper: Using optional classes to resolve XPATH expressions and traverse data trees across multiple models.

    Data Handling

    • Serialisation and Deserialisation: Using lib.serialise and lib.pybindJSON to output or load data instances.

    CLI and Usage

    • Usage: Documentation for command-line switches used by PyangBind.

    Practical Examples

    • example/oc-network-instance: Building static routes using the OpenConfig network-instance module.
    • example/simple-rpc: Manipulating YANG rpc definitions.
    • example/simple-serialise: Demonstrating serialisation and deserialisation workflows.
  3. How RPCs are handled in PyangBind

    master

    PyangBind generates bindings for RPCs defined in YANG modules. Because RPCs are not bound to a specific location in the data tree, they are generated in a separate module named <yang module name>_rpcs.

    Key characteristics of RPC bindings:

    • No Path Registration: All RPC bindings have register_paths set to False. They do not use a path_helper for register() or unregister() operations, though path_helper is still used to resolve leafref values or XPATH expressions.
    • Structure: Every generated RPC class contains two member containers, input and output, following the RFC6020 specification. These act as YANG containers for the RPC's data definitions.
  4. Supported JSON formats in PyangBind

    master

    PyangBind supports three primary JSON-based formats for serialisation and deserialisation:

    1. XML (RFC 7950): While mentioned as a supported format, the documentation notes a current bias towards JSON, with XML serialisation modules expected in the future.
    2. IETF JSON: Defined in draft-ietf-netmod-yang-json-08. This format typically uses module prefixes for keys (e.g., "module_name:container_name") and represents lists as arrays of objects.
    3. OpenConfig/PyangBind JSON: A format without a published specification, used primarily for loading entire modules into new instances.
  5. Core PyangBind classes and functions

    master

    PyangBind provides several core modules for managing YANG data, serialization, and path lookups:

    • pyangbind.base.PybindBase: The parent class inherited by all container or module YANG objects.
    • pyangbind.pybindJSON: Contains wrapper functions to assist with serializing YANG data to JSON.
    • pyangbind.serialise.pybindJSONEncoder: A custom encoder for the standard Python json module, used to serialize PyangBind class hierarchies to JSON.
    • pyangbind.serialise.pybindJSONDecoder: A custom decoder for the standard Python json module, used to load JSON-encoded YANG model instances back into a PyangBind class hierarchy.
    • pyangbind.xpathhelper.YANGPathHelper: A class that allows objects to be registered and subsequently retrieved using XPATH expressions.
  6. Enable XPath lookup with --use-xpathhelper

    master

    By default, XPATH references in generated classes (used in when or leaf-ref statements) are treated as simple strings.

    If you specify --use-xpathhelper, PyangBind will pass a path_helper object (provided during class instantiation) to all child objects. This allows the classes to perform actual lookups for XPATH expressions. See xpathhelper.md for implementation details.

  7. How extension methods (`extmethods`) work in PyangBind

    master

    Extension methods allow you to bind arbitrary Python methods to specific XPATH paths within a YANG data tree. This is useful for tying operational logic (like a soft_reset command) directly to a data instance in an NMS implementation.

    Key Concepts

    • Path Mapping: You provide a dictionary mapping an XPATH to a class instance. The XPATH must be the path to the object without filtering attributes (e.g., use /bgp/neighbors/neighbor/config/enabled instead of /bgp/neighbors/neighbor[peer-addr='1.1.1.1']/config/enabled).
    • Method Proxying: When an object is instantiated, it checks the extmethods dictionary. If its path matches an entry, it inherits all methods from the provided class instance.
    • Collision Avoidance: To prevent conflicts with actual YANG data element names, all proxied methods are prefixed with an underscore (_).
    • Scope: You cannot bind an extension method to a single specific instance (e.g., a specific neighbor IP); instead, you bind it to the path, making the method available to all instances at that path.
    # Example of the dictionary structure
    extmethods = {
        "/path/to/object/one": <Class Instance>,
        "/path/to/object/two": <Class instance>
    }
  8. How PyangBind maps YANG classes to Python

    master

    PyangBind maps YANG data types to built-in Python types whenever possible (e.g., YANG string to Python str/unicode). However, every mapped class is wrapped in a meta-class that inherits from pyangbind.lib.yangtypes.YANGBaseClass.

    This wrapper provides essential YANG-specific metadata and functionality, including:

    • Storing the original YANG name of the object.
    • Tracking the object's path within the data tree.
    • Determining if a value has changed from its default.
    • Managing namespaces.

    Types are dynamically generated at instantiation time using the YANGDynClass function.

  9. How XPathHelper works in PyangBind

    master

    YANG data models use a tree structure where nodes (containers, leaves, etc.) are referenced via XPATH expressions (e.g., in leafref or augment statements). To resolve these references, PyangBind uses a path_helper object passed to all PyangBind classes.

    PyangbindXpathHelper is the interface (skeleton class) that defines the required methods for any helper implementation:

    • register(path, object_ptr, caller=False): Called when a PyangBind object is created to map a path to an object_ptr.
    • unregister(path, caller=False): Called when an object is removed to clean up the mapping.
    • get(path, caller=False): Used to retrieve all data nodes matching a specific XPATH.

    This architecture allows for different implementations, such as a database-backed helper instead of an in-memory one.

  10. Use YANGPathHelper for in-memory XPATH resolution

    master

    The YANGPathHelper class in pyangbind.lib.xpathhelper provides an in-memory implementation of the XPathHelper interface. It maintains a lightweight XML representation of the data tree where each element contains an obj_ptr attribute referencing the actual PyangBind object.

    To use it, you must ensure your bindings were generated with the --use-xpathhelper flag.

    Key Methods:

    • get(path, caller=False): Returns a list of all objects matching the XPATH.
    • get_unique(path, caller=False): Returns a single object matching the XPATH. It raises an exception if more than one object matches.
    • tostring(pretty_print=False): Returns the internal XML representation of the tree.
    from openconfig import openconfig_bgp
    from pyangbind.lib.xpathhelper import YANGPathHelper
    
    ph = YANGPathHelper()
    # Pass the helper to the root object via path_helper kwarg
    ob = openconfig_bgp(path_helper=ph)
    
    # Data is automatically registered as you build the tree
    peer = ob.bgp.neighbors.neighbor.add("192.0.2.1")
    peer.config.peer_as = 15169
    
    # Retrieve data using XPATH
    as_number = ph.get_unique("/bgp/neighbors/neighbor[neighbor-address='192.0.2.1']/config/peer-as")
  11. How Python module names are mapped from YANG

    master
    PyangBind generates Python modules named after the YANG module using Python-safe naming conventions. It replaces hyphens with underscores and appends underscores to reserved names. For example, openconfig-network-instance.yang becomes the module openconfig_network_instance.
  12. How YANGDynClass provides metadata and hierarchy information

    master

    PyangBind uses a meta-class called YANGDynClass to wrap base YANG types. This wrapper injects several generic methods and variables that allow developers to interact with the underlying YANG schema logic without manual tracking.

    Key capabilities provided by YANGDynClass include:

    • Schema Awareness: Accessing the _namespace, _defining_module, yang_name(), and _is_config status.
    • Change Tracking: Using _changed() to detect if a value or container has been manipulated.
    • Default Values: Using default() to retrieve the default value specified in the YANG module (even if the current instance value is the type's null value).
    • Choice Handling: Using _choice to identify which case of a choice statement an element belongs to.
    • Identity/Key Metadata: Using _is_keyval to identify if a leaf is a list key.