### GET - Retrieve Configuration and State Data Source: https://context7.com/akarneliuk/pygnmi/llms.txt The get() method retrieves configuration and operational state data from specified paths on the network device. It supports multiple paths, different data types, and various encodings. ```APIDOC ## GET /gnmi ### Description Retrieves configuration and operational state data from specified paths on the network device. Supports multiple paths, different data types, and various encodings. ### Method GET ### Endpoint /gnmi ### Parameters #### Query Parameters - **path** (list of strings) - Required - The paths to retrieve data from. - **encoding** (string) - Optional - The encoding format for the data (e.g., 'json', 'json_ietf'). - **datatype** (string) - Optional - Specifies whether to retrieve 'config' or 'state' data. - **prefix** (string) - Optional - A common path prefix for all specified paths. - **target** (string) - Optional - The target device for path-based routing. ### Request Example ```python from pygnmi.client import gNMIclient import json host = ('192.168.1.1', '57400') with gNMIclient(target=host, username='admin', password='admin', insecure=True) as gc: # Get multiple paths with JSON encoding paths = [ 'openconfig-interfaces:interfaces', 'openconfig-network-instance:network-instances' ] result = gc.get(path=paths, encoding='json') print(json.dumps(result, indent=2)) # Get specific interface with key selector result = gc.get( path=['openconfig-interfaces:interfaces/interface[name=Ethernet1]'], encoding='json_ietf' ) # Get only configuration data result = gc.get( path=['openconfig-interfaces:interfaces'], datatype='config' ) # Get only operational state result = gc.get( path=['openconfig-interfaces:interfaces'], datatype='state' ) # Get with prefix (common path prefix for all paths) result = gc.get( prefix='openconfig-interfaces:interfaces', path=['interface[name=Ethernet1]/config', 'interface[name=Ethernet2]/config'] ) # Get with target (for path-based routing) result = gc.get( path=['openconfig-interfaces:interfaces'], target='leaf1' ) ``` ### Response #### Success Response (200) - **notification** (list) - A list of notifications containing the retrieved data. - **timestamp** (int) - The timestamp of the notification. - **prefix** (string) - The prefix of the paths in the notification. - **update** (list) - A list of updates, each containing a path and its value. - **path** (string) - The path of the updated data. - **val** (any) - The value of the data. #### Response Example ```json { "notification": [ { "timestamp": 1699900000000000000, "prefix": "interfaces", "alias": null, "atomic": false, "update": [ { "path": "interface[name=Ethernet1]/state/admin-status", "val": "UP" } ] } ] } ``` ``` -------------------------------- ### Retrieve Full Device Configuration Source: https://github.com/akarneliuk/pygnmi/blob/master/README.rst Retrieve the complete device configuration by passing an empty path to the get method. ```python get(path[]) ``` -------------------------------- ### Initialize Nornir and run gNMI tasks Source: https://context7.com/akarneliuk/pygnmi/llms.txt This Python code demonstrates initializing Nornir with a configuration file and then running gNMI tasks (capabilities, get, set) across the network inventory. Ensure your 'config.yaml' file is properly set up. ```python # Initialize Nornir with inventory # config.yaml should define hosts with hostname, port, username, password nr = InitNornir(config_file='config.yaml') # Run capabilities on all devices cap_results = nr.run(task=gnmi_capabilities) for host, result in cap_results.items(): print(f"{host}: gNMI version {result.result.get('gnmi_version')}") # Get interfaces from all devices get_results = nr.run( task=gnmi_get, path=['openconfig-interfaces:interfaces'] ) # Apply configuration to all devices update_data = [ ("openconfig-system:system/config/hostname", "configured-by-nornir") ] set_results = nr.run( task=gnmi_set, update=update_data ) ``` -------------------------------- ### Perform gNMI Operations with pygnmicli Source: https://context7.com/akarneliuk/pygnmi/llms.txt Command-line interface for executing gNMI operations like get, set, and subscribe without writing Python code. ```bash # Get device capabilities pygnmicli -t 192.168.1.1:57400 -u admin -p admin -i -o capabilities # Get configuration data pygnmicli -t 192.168.1.1:57400 -u admin -p admin -i \ -o get \ -x openconfig-interfaces:interfaces \ -e json_ietf # Get multiple paths pygnmicli -t 192.168.1.1:57400 -u admin -p admin -i \ -o get \ -x openconfig-interfaces:interfaces openconfig-system:system \ -d config # Set configuration (update) pygnmicli -t 192.168.1.1:57400 -u admin -p admin -i \ -o set-update \ -x openconfig-interfaces:interfaces/interface[name=Loopback0]/config \ -f config.json \ -e json_ietf # Set configuration (replace) pygnmicli -t 192.168.1.1:57400 -u admin -p admin -i \ -o set-replace \ -x openconfig-interfaces:interfaces/interface[name=Ethernet1]/config \ -f new_config.json # Delete configuration pygnmicli -t 192.168.1.1:57400 -u admin -p admin -i \ -o set-delete \ -x openconfig-interfaces:interfaces/interface[name=Loopback0] # Stream telemetry subscription pygnmicli -t 192.168.1.1:57400 -u admin -p admin -i \ -o subscribe-stream \ -x openconfig-interfaces:interfaces/interface/state/counters \ -e json # Once subscription pygnmicli -t 192.168.1.1:57400 -u admin -p admin -i \ -o subscribe-once \ -x openconfig-interfaces:interfaces # With TLS and certificate pygnmicli -t 192.168.1.1:57400 -u admin -p admin \ -c /path/to/cert.pem \ -O device.example.com \ -o get \ -x openconfig-interfaces:interfaces # With token authentication pygnmicli -t 192.168.1.1:443 --token YOUR_TOKEN --skip-verify \ -o capabilities # With history extension (snapshot) pygnmicli -t 192.168.1.1:443 --token YOUR_TOKEN --skip-verify \ -o subscribe-once \ -x openconfig-interfaces:interfaces \ --ext-history-snapshot-time "2024-01-15T10:00:00Z" # With history extension (range) pygnmicli -t 192.168.1.1:443 --token YOUR_TOKEN --skip-verify \ -o subscribe-stream \ -x openconfig-interfaces:interfaces/interface/state/counters \ --ext-history-range-start "2024-01-15T08:00:00Z" \ --ext-history-range-end "2024-01-15T10:00:00Z" # Debug mode to see Protobuf messages pygnmicli -t 192.168.1.1:57400 -u admin -p admin -i \ -o get \ -x openconfig-interfaces:interfaces \ -D ``` -------------------------------- ### Connect and Get Interface/ACL Data with pyGNMI Source: https://github.com/akarneliuk/pygnmi/blob/master/README.rst This snippet demonstrates how to establish an insecure gRPC connection to a network device using pyGNMI and retrieve interface and ACL configuration data. Ensure the host, username, and password are set correctly for your environment. ```python3 # Modules from pygnmi.client import gNMIclient # Variables host = ('169.254.255.64', '57400') # Body if __name__ == '__main__': with gNMIclient(target=host, username='admin', password='admin', insecure=True) as gc: result = gc.get(path=['openconfig-interfaces:interfaces', 'openconfig-acl:acl']) print(result) ``` -------------------------------- ### Get configuration/state via gNMI Source: https://context7.com/akarneliuk/pygnmi/llms.txt This Nornir task fetches configuration or state data from a device using gNMI. Specify the desired path and encoding (default is 'json'). ```python def gnmi_get(task: Task, path: list, encoding: str = 'json') -> Result: """Get configuration/state via gNMI""" with gNMIclient( target=(task.host.hostname, task.host.port), username=task.host.username, password=task.host.password, insecure=True ) as gc: result = gc.get(path=path, encoding=encoding) return Result(host=task.host, result=result) ``` -------------------------------- ### Test gNMI Get Operation Source: https://github.com/akarneliuk/pygnmi/blob/master/pygnmi.egg-info/SOURCES.txt Tests the 'get' operation to retrieve data from the gNMI server. ```python def test_get_operation(): conn = client.connect('localhost', 50051, insecure=True) paths = ['system/clock/current-datetime'] response = client.get(conn, paths) assert response is not None ``` -------------------------------- ### Get device capabilities via gNMI Source: https://context7.com/akarneliuk/pygnmi/llms.txt This Nornir task retrieves gNMI capabilities from a device. Ensure Nornir is initialized with host details including hostname, port, username, and password. ```python from pygnmi.client import gNMIclient from nornir import InitNornir from nornir.core.task import Task, Result # Define Nornir tasks for gNMI operations def gnmi_capabilities(task: Task) -> Result: """Get device capabilities via gNMI""" with gNMIclient( target=(task.host.hostname, task.host.port), username=task.host.username, password=task.host.password, insecure=True ) as gc: result = gc.capabilities() return Result(host=task.host, result=result) ``` -------------------------------- ### Get gNMI Data Source: https://github.com/akarneliuk/pygnmi/blob/master/pygnmi.egg-info/SOURCES.txt Retrieves data from a gNMI server for the specified paths. Supports different encodings. ```python response = client.get(conn, paths, encoding=encoding) ``` -------------------------------- ### Initialize gNMIclient with various authentication methods Source: https://context7.com/akarneliuk/pygnmi/llms.txt Demonstrates connecting to network devices using insecure, certificate-based, mutual TLS, token-based, and keepalive-enabled configurations. ```python from pygnmi.client import gNMIclient # Basic insecure connection (no TLS) host = ('192.168.1.1', '57400') with gNMIclient(target=host, username='admin', password='admin', insecure=True) as gc: result = gc.capabilities() print(result) # Secure connection with certificate with gNMIclient( target=('10.0.0.1', '57400'), username='admin', password='admin', path_cert='/path/to/cert.pem', override='device.example.com' ) as gc: result = gc.capabilities() # Mutual TLS authentication with gNMIclient( target=('10.0.0.1', '57400'), path_root='/path/to/ca.crt', path_cert='/path/to/client.crt', path_key='/path/to/client.key', override='device.example.com' ) as gc: result = gc.get(path=['openconfig-interfaces:interfaces']) # Token-based authentication (e.g., for Arista CVP) with open("token.tok") as f: TOKEN = f.read().strip('\n') with gNMIclient( target=('192.168.0.5', '443'), token=TOKEN, skip_verify=True ) as gc: result = gc.capabilities() # With keepalive for long-running connections gc = gNMIclient( target=('192.168.1.1', '57400'), username='admin', password='admin', insecure=True, keepalive_time_ms=10000 ) gc.connect() # ... perform operations ... gc.close() ``` -------------------------------- ### Compare before/after state for set operations Source: https://context7.com/akarneliuk/pygnmi/llms.txt Use this command-line interface to compare the state of a device before and after a set operation. ```bash pygnmicli -t 192.168.1.1:57400 -u admin -p admin -i \ -o set-update \ -x openconfig-interfaces:interfaces/interface[name=Ethernet1]/config \ -f config.json \ -C print ``` -------------------------------- ### Set Configuration with Automatic Retry Source: https://context7.com/akarneliuk/pygnmi/llms.txt Use set_with_retry for configuration changes that might fail due to transient issues like device startup or lock contention. It automatically retries on FAILED_PRECONDITION errors. ```python from pygnmi.client import gNMIclient host = ('192.168.1.1', '57400') with gNMIclient(target=host, username='admin', password='admin', insecure=True) as gc: update_data = [ ( "openconfig-interfaces:interfaces/interface[name=Ethernet1]/config/description", "Updated description" ) ] # Will retry once after 3 seconds if FAILED_PRECONDITION occurs result = gc.set_with_retry( update=update_data, encoding='json_ietf', retry_delay=3 # seconds to wait before retry ) print(result) ``` -------------------------------- ### View Configuration Changes with show_diff Source: https://context7.com/akarneliuk/pygnmi/llms.txt Configure the gNMI client with `show_diff='print'` to display a colored diff of configuration changes directly in the console after a `set()` operation. Alternatively, use `show_diff='get'` to retrieve the diff as a list. ```python # Using show_diff to see configuration changes with gNMIclient( target=host, username='admin', password='admin', insecure=True, show_diff='print' # or 'get' to return diff list ) as gc: result = gc.set(update=update_data, encoding='json_ietf') # Prints colored diff showing + (additions) and - (removals) ``` -------------------------------- ### Connect to gNMI Server (Secure) Source: https://github.com/akarneliuk/pygnmi/blob/master/pygnmi.egg-info/SOURCES.txt Establishes a secure TLS connection to a gNMI server. Requires certificate and key files. ```python conn = client.connect(host, port, pem_file=pem_file, key_file=key_file, ca_file=ca_file, target_name=target_name) ``` -------------------------------- ### Connect to gNMI Server (Insecure) Source: https://github.com/akarneliuk/pygnmi/blob/master/pygnmi.egg-info/SOURCES.txt Establishes an insecure connection to a gNMI server. Use with caution, as data is not encrypted. ```python conn = client.connect(host, port, insecure=True) ``` -------------------------------- ### Create gNMI Extension from File Source: https://github.com/akarneliuk/pygnmi/blob/master/pygnmi.egg-info/SOURCES.txt Loads gNMI extensions from a specified file. This allows for custom extensions to be used in gNMI operations. ```python def create_gnmi_extension_from_file(file_path): return create_gnmi_extension(file_path) ``` -------------------------------- ### gNMIclient Initialization Source: https://context7.com/akarneliuk/pygnmi/llms.txt The gNMIclient class is the primary interface for connecting to network devices. It supports insecure connections, certificate-based TLS, mutual TLS, and token-based authentication. ```APIDOC ## gNMIclient Initialization ### Description Initializes a connection to a network device using the gNMI protocol. Supports context manager usage for automatic resource cleanup. ### Parameters #### Request Body - **target** (tuple) - Required - Host and port tuple (e.g., ('192.168.1.1', '57400')) - **username** (str) - Optional - Username for authentication - **password** (str) - Optional - Password for authentication - **insecure** (bool) - Optional - Disable TLS if set to True - **path_cert** (str) - Optional - Path to certificate file - **path_root** (str) - Optional - Path to CA certificate - **path_key** (str) - Optional - Path to private key file - **token** (str) - Optional - Authentication token - **keepalive_time_ms** (int) - Optional - Keepalive interval in milliseconds ``` -------------------------------- ### Retrieve Specific Interface with Key Selector Source: https://context7.com/akarneliuk/pygnmi/llms.txt Fetches data for a specific interface by using a key selector in the path. This allows for precise targeting of configuration or state information. ```python result = gc.get( path=['openconfig-interfaces:interfaces/interface[name=Ethernet1]'], encoding='json_ietf' ) ``` -------------------------------- ### Test gNMI Subscription (Once) Source: https://github.com/akarneliuk/pygnmi/blob/master/pygnmi.egg-info/SOURCES.txt Tests the 'subscribe' operation in ONCE mode. ```python def test_subscribe_once(): conn = client.connect('localhost', 50051, insecure=True) paths = ['system/clock/current-datetime'] response = client.subscribe(conn, paths, subscription_mode='ONCE') assert response is not None ``` -------------------------------- ### Update Device Configuration with Merge Operation Source: https://context7.com/akarneliuk/pygnmi/llms.txt Use the `update` parameter in the `set()` method to merge new configuration data into the existing device configuration. This is useful for adding or modifying specific parameters. ```python from pygnmi.client import gNMIclient host = ('192.168.1.1', '57400') with gNMIclient(target=host, username='admin', password='admin', insecure=True) as gc: # Update operation - merge configuration update_data = [ ( "openconfig-interfaces:interfaces/interface[name=Loopback0]", { "config": { "name": "Loopback0", "enabled": True, "type": "softwareLoopback", "description": "Management Loopback" }, "subinterfaces": { "subinterface": [{ "index": 0, "config": { "index": 0, "enabled": True }, "openconfig-if-ip:ipv4": { "addresses": { "address": [{ "ip": "10.0.255.1", "config": { "ip": "10.0.255.1", "prefix-length": 32 } }] } } }] } } ) ] result = gc.set(update=update_data, encoding='json_ietf') print(result) ``` -------------------------------- ### Set Configuration with Master Arbitration Source: https://context7.com/akarneliuk/pygnmi/llms.txt Coordinates configuration changes in multi-controller environments using election IDs. ```python from pygnmi.client import gNMIclient host = ('192.168.1.1', '57400') with gNMIclient(target=host, username='admin', password='admin', insecure=True) as gc: update_data = [ ( "openconfig-interfaces:interfaces/interface[name=Ethernet1]/config/description", "Controlled by master" ) ] # Set with master arbitration extension extension = { 'master_arbitration': { 'election_id': { 'high': 0, 'low': 12345 }, 'role': { 'id': 'primary-controller' } } } result = gc.set( update=update_data, encoding='json_ietf', extension=extension ) print(result) ``` -------------------------------- ### Delete Configuration Path Source: https://context7.com/akarneliuk/pygnmi/llms.txt Use the `delete` parameter in the `set()` method to remove a specified configuration path from the device. This is useful for cleaning up or removing unused configurations. ```python # Delete operation delete_paths = [ "openconfig-interfaces:interfaces/interface[name=Loopback0]" ] result = gc.set(delete=delete_paths) ``` -------------------------------- ### Retrieve Data with Path Prefix Source: https://context7.com/akarneliuk/pygnmi/llms.txt This method allows specifying a common path prefix for all subsequent paths, simplifying requests when dealing with nested configurations. ```python # Get with prefix (common path prefix for all paths) result = gc.get( prefix='openconfig-interfaces:interfaces', path=['interface[name=Ethernet1]/config', 'interface[name=Ethernet2]/config'] ) ``` -------------------------------- ### Replace Device Configuration Source: https://context7.com/akarneliuk/pygnmi/llms.txt Employ the `replace` parameter in the `set()` method to overwrite an entire configuration path with new data. This is suitable for wholesale changes to a section of the configuration. ```python # Replace operation - overwrite entire path replace_data = [ ( "openconfig-interfaces:interfaces/interface[name=Ethernet1]/config", { "name": "Ethernet1", "enabled": True, "description": "Uplink to spine" } ) ] result = gc.set(replace=replace_data, encoding='json_ietf') ``` -------------------------------- ### Query device capabilities with capabilities() Source: https://context7.com/akarneliuk/pygnmi/llms.txt Retrieves and parses the gNMI capabilities of a target device, including supported models, encodings, and the gNMI version. ```python from pygnmi.client import gNMIclient host = ('192.168.1.1', '57400') with gNMIclient(target=host, username='admin', password='admin', insecure=True) as gc: result = gc.capabilities() # Example response: # { # 'supported_models': [ # {'name': 'openconfig-interfaces', 'organization': 'OpenConfig', 'version': '2.0.0'}, # {'name': 'openconfig-network-instance', 'organization': 'OpenConfig', 'version': '1.0.0'} # ], # 'supported_encodings': ['json', 'json_ietf', 'proto'], # 'gnmi_version': '0.8.0' # } print(f"gNMI Version: {result.get('gnmi_version')}") print(f"Supported Encodings: {result.get('supported_encodings')}") for model in result.get('supported_models', []): print(f"Model: {model['name']} v{model['version']}") ``` -------------------------------- ### High-Level Telemetry Subscription with subscribe2 Source: https://context7.com/akarneliuk/pygnmi/llms.txt The subscribe2 method offers a versatile interface for telemetry subscriptions. It supports 'stream' for continuous updates, 'once' for a single snapshot, and 'poll' for on-demand retrieval. This is recommended for building telemetry collectors. ```python from pygnmi.client import gNMIclient host = ('192.168.1.1', '57400') # Stream subscription - continuous updates subscribe_request = { 'subscription': [ { 'path': 'openconfig-interfaces:interfaces/interface[name=Ethernet1]', 'mode': 'sample', 'sample_interval': 10000000000 # 10 seconds in nanoseconds }, { 'path': 'openconfig-interfaces:interfaces/interface[name=Ethernet2]', 'mode': 'on_change' } ], 'mode': 'stream', 'encoding': 'json' } with gNMIclient(target=host, username='admin', password='admin', insecure=True) as gc: telemetry_stream = gc.subscribe2(subscribe=subscribe_request) for telemetry_entry in telemetry_stream: print(telemetry_entry) # Example output: # { # 'update': { # 'timestamp': 1699900000000000000, # 'prefix': 'interfaces/interface[name=Ethernet1]', # 'update': [{'path': 'state/counters/in-octets', 'val': 123456789}] # } # } ``` ```python # Once subscription - get current state then close once_request = { 'subscription': [ {'path': 'openconfig-interfaces:interfaces'} ], 'mode': 'once', 'encoding': 'json_ietf' } with gNMIclient(target=host, username='admin', password='admin', insecure=True) as gc: for entry in gc.subscribe2(subscribe=once_request): print(entry) if 'sync_response' in entry: break # End of once subscription ``` ```python # Poll subscription - on-demand updates poll_request = { 'subscription': [ {'path': 'openconfig-interfaces:interfaces'} ], 'mode': 'poll', 'encoding': 'json_ietf' } with gNMIclient(target=host, username='admin', password='admin', insecure=True) as gc: poll_sub = gc.subscribe2(subscribe=poll_request) # Get initial state initial = poll_sub.get_update(timeout=5) print(initial) # Poll again when needed import time time.sleep(10) updated = poll_sub.get_update(timeout=5) print(updated) poll_sub.close() ``` -------------------------------- ### capabilities() Source: https://context7.com/akarneliuk/pygnmi/llms.txt Retrieves the gNMI capabilities of the target network device, including supported models, encodings, and the gNMI version. ```APIDOC ## capabilities() ### Description Queries the target device for its supported gNMI capabilities. ### Response #### Success Response (200) - **supported_models** (list) - List of supported YANG models - **supported_encodings** (list) - List of supported data encodings (e.g., json, proto) - **gnmi_version** (str) - The gNMI protocol version supported by the device ### Response Example { "supported_models": [ {"name": "openconfig-interfaces", "organization": "OpenConfig", "version": "2.0.0"} ], "supported_encodings": ["json", "json_ietf", "proto"], "gnmi_version": "0.8.0" } ``` -------------------------------- ### Combine Set Operations Source: https://context7.com/akarneliuk/pygnmi/llms.txt Perform multiple configuration operations (delete, update) in a single `set()` request for efficiency. This allows for atomic changes across different parts of the configuration. ```python # Combined operations in single request result = gc.set( delete=["openconfig-interfaces:interfaces/interface[name=Loopback99]"] update=[ ("openconfig-interfaces:interfaces/interface[name=Loopback1]/config", {"name": "Loopback1", "enabled": True}) ], encoding='json_ietf' ) ``` -------------------------------- ### Subscribe to gNMI Data (Once) Source: https://github.com/akarneliuk/pygnmi/blob/master/pygnmi.egg-info/SOURCES.txt Establishes a one-time subscription to receive a single data update from a gNMI server. ```python response = client.subscribe(conn, paths, subscription_mode='ONCE', encoding=encoding) ``` -------------------------------- ### Configure gNMI Path Naming Conventions Source: https://github.com/akarneliuk/pygnmi/blob/master/README.rst Supported path formats for gNMI operations. ```text yang-module:container/container[key=value] ``` ```text /yang-module:container/container[key=value] ``` ```text /yang-module:/container/container[key=value] ``` ```text /container/container[key=value] ``` -------------------------------- ### Test String Path Creation Source: https://github.com/akarneliuk/pygnmi/blob/master/pygnmi.egg-info/SOURCES.txt Tests the functionality of creating gNMI paths from string representations. ```python def test_create_string_path(): path_str = 'interfaces/interface/config/description' path = create_gnmi_path_from_string(path_str) assert len(path.elem) == 4 assert path.elem[0].name == 'interfaces' ``` -------------------------------- ### Retrieve Multiple Paths with JSON Encoding Source: https://context7.com/akarneliuk/pygnmi/llms.txt Use this to fetch data from multiple specified paths on a network device using JSON encoding. Ensure the gNMI client is initialized with target, username, and password. ```python from pygnmi.client import gNMIclient import json host = ('192.168.1.1', '57400') with gNMIclient(target=host, username='admin', password='admin', insecure=True) as gc: # Get multiple paths with JSON encoding paths = [ 'openconfig-interfaces:interfaces', 'openconfig-network-instance:network-instances' ] result = gc.get(path=paths, encoding='json') print(json.dumps(result, indent=2)) ``` -------------------------------- ### Subscribe to gNMI Data (Stream) Source: https://github.com/akarneliuk/pygnmi/blob/master/pygnmi.egg-info/SOURCES.txt Establishes a streaming subscription to receive data updates from a gNMI server. Supports various subscription modes and options. ```python for response in client.subscribe(conn, paths, subscription_mode=subscription_mode, sample_interval=sample_interval, suppress_redundant=suppress_redundant, encoding=encoding): # Process subscription updates pass ``` -------------------------------- ### Retrieve Only Configuration Data Source: https://context7.com/akarneliuk/pygnmi/llms.txt Use the `datatype='config'` argument to retrieve only the configuration-related data for the specified paths. ```python # Get only configuration data result = gc.get( path=['openconfig-interfaces:interfaces'], datatype='config' ) ``` -------------------------------- ### POST - Modify Device Configuration Source: https://context7.com/akarneliuk/pygnmi/llms.txt The set() method modifies the configuration on the network device. It supports three operations: update (merge), replace, and delete. Multiple operations can be combined in a single request. ```APIDOC ## POST /gnmi ### Description Modifies the configuration on the network device. Supports update (merge), replace, and delete operations, which can be combined in a single request. ### Method POST ### Endpoint /gnmi ### Parameters #### Query Parameters - **encoding** (string) - Optional - The encoding format for the data (e.g., 'json', 'json_ietf'). - **show_diff** (string) - Optional - Controls how configuration diffs are handled ('print' or 'get'). #### Request Body - **update** (list of tuples) - Optional - Data to update or merge. Each tuple contains a path (string) and a configuration object. - **replace** (list of tuples) - Optional - Data to replace. Each tuple contains a path (string) and a configuration object. - **delete** (list of strings) - Optional - Paths to delete. ### Request Example ```python from pygnmi.client import gNMIclient host = ('192.168.1.1', '57400') with gNMIclient(target=host, username='admin', password='admin', insecure=True) as gc: # Update operation - merge configuration update_data = [ ( "openconfig-interfaces:interfaces/interface[name=Loopback0]", { "config": { "name": "Loopback0", "enabled": True, "type": "softwareLoopback", "description": "Management Loopback" }, "subinterfaces": { "subinterface": [{ "index": 0, "config": { "index": 0, "enabled": True }, "openconfig-if-ip:ipv4": { "addresses": { "address": [{ "ip": "10.0.255.1", "config": { "ip": "10.0.255.1", "prefix-length": 32 } }] } } }] } } ) ] result = gc.set(update=update_data, encoding='json_ietf') print(result) # Replace operation - overwrite entire path replace_data = [ ( "openconfig-interfaces:interfaces/interface[name=Ethernet1]/config", { "name": "Ethernet1", "enabled": True, "description": "Uplink to spine" } ) ] result = gc.set(replace=replace_data, encoding='json_ietf') # Delete operation delete_paths = [ "openconfig-interfaces:interfaces/interface[name=Loopback0]" ] result = gc.set(delete=delete_paths) # Combined operations in single request result = gc.set( delete=["openconfig-interfaces:interfaces/interface[name=Loopback99]"] update=[ ("openconfig-interfaces:interfaces/interface[name=Loopback1]/config", {"name": "Loopback1", "enabled": True}) ], encoding='json_ietf' ) # Using show_diff to see configuration changes with gNMIclient( target=host, username='admin', password='admin', insecure=True, show_diff='print' # or 'get' to return diff list ) as gc: result = gc.set(update=update_data, encoding='json_ietf') ``` ### Response #### Success Response (200) - **timestamp** (int) - The timestamp of the operation. - **prefix** (string) - The prefix of the paths affected by the operation. - **response** (list) - A list of responses for each operation performed. - **path** (string) - The path affected by the operation. - **op** (string) - The type of operation performed (e.g., 'UPDATE', 'REPLACE', 'DELETE'). #### Response Example ```json { "timestamp": 1699900000000000000, "prefix": null, "response": [ { "path": "openconfig-interfaces:interfaces/interface[name=Loopback0]", "op": "UPDATE" } ] } ``` ``` -------------------------------- ### Enable Debug Mode Source: https://github.com/akarneliuk/pygnmi/blob/master/README.rst Enable debug mode during object creation to inspect Protobuf messages. ```python debug=True ``` -------------------------------- ### Test Insecure Connection Source: https://github.com/akarneliuk/pygnmi/blob/master/pygnmi.egg-info/SOURCES.txt Tests establishing an insecure connection to the gNMI server. ```python def test_connect_insecure(): conn = client.connect('localhost', 50051, insecure=True) assert conn is not None ``` -------------------------------- ### Test gNMI Extension Loading Source: https://github.com/akarneliuk/pygnmi/blob/master/pygnmi.egg-info/SOURCES.txt Tests the functionality of loading gNMI extensions from a file. ```python def test_create_gnmi_extension_from_file(): # Assume 'test_extension.txt' exists with some content extension = create_gnmi_extension_from_file('test_extension.txt') assert isinstance(extension, gnmi_ext_pb2.Extension) ``` -------------------------------- ### subscribe2() - High-Level Telemetry Subscription Source: https://context7.com/akarneliuk/pygnmi/llms.txt Provides a high-level interface for telemetry subscriptions supporting stream, once, and poll modes. Recommended for building telemetry collectors. ```APIDOC ## subscribe2() ### Description Provides a high-level interface for telemetry subscriptions supporting stream, once, and poll modes. This is the recommended method for building telemetry collectors. ### Method POST (implied by subscription operation) ### Endpoint Not explicitly defined, operates on the gNMI client's target. ### Parameters #### Request Body - **subscribe** (dict) - Required - A dictionary defining the subscription parameters. - **subscription** (list of dict) - Required - List of subscription details. - **path** (string) - Required - The gNMI path to subscribe to. - **mode** (string) - Optional - Subscription mode ('sample', 'on_change', 'target_defined'). - **sample_interval** (int) - Optional - Sample interval in nanoseconds (for 'sample' mode). - **mode** (string) - Required - Subscription mode ('stream', 'once', 'poll'). - **encoding** (string) - Required - Encoding format (e.g., 'json', 'json_ietf'). ### Request Example (Stream) ```python subscribe_request = { 'subscription': [ { 'path': 'openconfig-interfaces:interfaces/interface[name=Ethernet1]', 'mode': 'sample', 'sample_interval': 10000000000 # 10 seconds in nanoseconds }, { 'path': 'openconfig-interfaces:interfaces/interface[name=Ethernet2]', 'mode': 'on_change' } ], 'mode': 'stream', 'encoding': 'json' } telemetry_stream = gc.subscribe2(subscribe=subscribe_request) ``` ### Response (Stream) #### Success Response (200) - **telemetry_entry** (dict) - A dictionary containing telemetry data. - **update** (dict) - Contains telemetry updates. - **timestamp** (int) - Timestamp of the update. - **prefix** (string) - gNMI prefix for the update. - **update** (list of dict) - List of individual updates. - **path** (string) - Path of the updated element. - **val** (any) - Value of the updated element. #### Response Example (Stream) ```json { "update": { "timestamp": 1699900000000000000, "prefix": "interfaces/interface[name=Ethernet1]", "update": [ {"path": "state/counters/in-octets", "val": 123456789} ] } } ``` ### Request Example (Once) ```python once_request = { 'subscription': [ {'path': 'openconfig-interfaces:interfaces'} ], 'mode': 'once', 'encoding': 'json_ietf' } for entry in gc.subscribe2(subscribe=once_request): print(entry) if 'sync_response' in entry: break ``` ### Response Example (Once) ```json { "notification": [ { "timestamp": 1699900000000000000, "prefix": "interfaces", "update": [ { "path": "interface[name=Ethernet1]/config/description", "val": "Some description" } ] } ], "sync_response": true } ``` ### Request Example (Poll) ```python poll_request = { 'subscription': [ {'path': 'openconfig-interfaces:interfaces'} ], 'mode': 'poll', 'encoding': 'json_ietf' } poll_sub = gc.subscribe2(subscribe=poll_request) initial = poll_sub.get_update(timeout=5) print(initial) updated = poll_sub.get_update(timeout=5) print(updated) poll_sub.close() ``` ### Response Example (Poll) ```json { "notification": [ { "timestamp": 1699900000000000000, "prefix": "interfaces", "update": [ { "path": "interface[name=Ethernet1]/config/description", "val": "Initial description" } ] } ] } ``` ``` -------------------------------- ### Test gNMI Subscription (Stream) Source: https://github.com/akarneliuk/pygnmi/blob/master/pygnmi.egg-info/SOURCES.txt Tests the 'subscribe' operation in streaming mode. ```python def test_subscribe_stream(): conn = client.connect('localhost', 50051, insecure=True) paths = ['system/clock/current-datetime'] for response in client.subscribe(conn, paths, subscription_mode='STREAM'): assert response is not None break # Process one update and break ``` -------------------------------- ### Test XPath Creation Source: https://github.com/akarneliuk/pygnmi/blob/master/pygnmi.egg-info/SOURCES.txt Tests the functionality of creating gNMI paths from XPath expressions. ```python def test_create_xpath(): xpath = '/interfaces/interface[name=eth0]/config/description' path = create_gnmi_path_from_xpath(xpath) assert path.xpath == xpath ``` -------------------------------- ### Collect One-Time Telemetry with subscribe_once() Source: https://context7.com/akarneliuk/pygnmi/llms.txt Retrieves current state for specified paths and terminates automatically after data receipt. ```python from pygnmi.client import gNMIclient host = ('192.168.1.1', '57400') subscribe = { 'subscription': [ {'path': 'openconfig-interfaces:interfaces'}, {'path': 'openconfig-network-instance:network-instances'} ], 'mode': 'once', 'encoding': 'json_ietf' } with gNMIclient(target=host, username='admin', password='admin', insecure=True) as gc: once_sub = gc.subscribe_once(subscribe=subscribe) all_data = [] for entry in once_sub: if 'update' in entry: all_data.append(entry['update']) if 'sync_response' in entry: print("Received all data") break # Process collected data for data in all_data: print(f"Timestamp: {data.get('timestamp')}") for update in data.get('update', []): print(f" {update['path']}: {update['val']}") ``` -------------------------------- ### subscribe_once() - One-Time Telemetry Collection Source: https://context7.com/akarneliuk/pygnmi/llms.txt The subscribe_once() method retrieves the current state of specified paths and automatically terminates after receiving all data. It's suitable for collecting a snapshot of telemetry data. ```APIDOC ## subscribe_once() - One-Time Telemetry Collection ### Description The `subscribe_once()` method retrieves the current state of specified paths and automatically terminates after receiving all data. ### Method `subscribe_once` ### Endpoint N/A (Client-side method) ### Parameters #### Request Body - **subscribe** (dict) - Required - A dictionary defining the subscription parameters, including paths, mode ('once'), and encoding. ### Request Example ```python subscribe = { 'subscription': [ {'path': 'openconfig-interfaces:interfaces'}, {'path': 'openconfig-network-instance:network-instances'} ], 'mode': 'once', 'encoding': 'json_ietf' } ``` ### Response #### Success Response (200) - **update** (list) - Contains telemetry data updates. - **sync_response** (dict) - Indicates the completion of data retrieval. #### Response Example ```json { "timestamp": 1678886400000000000, "update": [ { "path": "openconfig-interfaces:interfaces", "val": { ... } } ] } ``` ``` -------------------------------- ### set_with_retry() - Set with Automatic Retry Source: https://context7.com/akarneliuk/pygnmi/llms.txt Performs a set operation with automatic retry on transient failures (FAILED_PRECONDITION). Useful during device startup or lock contention scenarios. ```APIDOC ## set_with_retry() ### Description Performs a set operation with automatic retry on transient failures (FAILED_PRECONDITION). Useful during device startup or lock contention scenarios. ### Method POST (implied by set operation) ### Endpoint Not explicitly defined, operates on the gNMI client's target. ### Parameters #### Request Body - **update** (list of tuples) - Required - A list of tuples, where each tuple contains a gNMI path and the value to set. - **encoding** (string) - Optional - The encoding format for the data (e.g., 'json_ietf'). - **retry_delay** (int) - Optional - Seconds to wait before retrying after a transient failure. ### Request Example ```python update_data = [ ( "openconfig-interfaces:interfaces/interface[name=Ethernet1]/config/description", "Updated description" ) ] result = gc.set_with_retry( update=update_data, encoding='json_ietf', retry_delay=3 # seconds to wait before retry ) ``` ### Response #### Success Response (200) - **result** (any) - The result of the set operation. #### Response Example ```json { "result": "Operation successful" } ``` ``` -------------------------------- ### Retrieve Data with Target for Path-Based Routing Source: https://context7.com/akarneliuk/pygnmi/llms.txt Specify a target to enable path-based routing, directing the request to a particular device or service within the network. ```python # Get with target (for path-based routing) result = gc.get( path=['openconfig-interfaces:interfaces'], target='leaf1' ) ``` -------------------------------- ### Query Historical Data with History Extension Source: https://context7.com/akarneliuk/pygnmi/llms.txt Queries historical telemetry using snapshot times or time ranges via the subscribe2 method. ```python from pygnmi.client import gNMIclient host = ('192.168.1.1', '443') # Read token for authentication with open("token.tok") as f: TOKEN = f.read().strip('\n') # Snapshot time query - get state at specific point in time subscribe_snapshot = { 'subscription': [ { 'path': 'openconfig:/interfaces/interface/state/counters', 'mode': 'target_defined' } ], 'mode': 'once', 'encoding': 'proto' } extension_snapshot = { 'history': { 'snapshot_time': '2024-01-15T10:00:00Z' # ISO format # Or use nanoseconds since epoch: 1705312800000000000 } } with gNMIclient(target=host, token=TOKEN, skip_verify=True) as gc: for item in gc.subscribe2( subscribe=subscribe_snapshot, target='leaf1', extension=extension_snapshot ): print(item) # Time range query - get data within a time window subscribe_range = { 'subscription': [ { 'path': 'openconfig:/interfaces/interface/state/counters', 'mode': 'target_defined' } ], 'mode': 'stream', # Range requires stream mode 'encoding': 'proto' } extension_range = { 'history': { 'range': { 'start': '2024-01-15T08:00:00Z', 'end': '2024-01-15T10:00:00Z' } } } with gNMIclient(target=host, token=TOKEN, skip_verify=True) as gc: for item in gc.subscribe2( subscribe=subscribe_range, target='leaf1', extension=extension_range ): print(item) ``` -------------------------------- ### Test Secure Connection Source: https://github.com/akarneliuk/pygnmi/blob/master/pygnmi.egg-info/SOURCES.txt Tests establishing a secure TLS connection to the gNMI server. ```python def test_connect_secure(): # Assuming valid certs and keys are available conn = client.connect('localhost', 50051, pem_file='cert.pem', key_file='key.pem', ca_file='ca.pem', target_name='example.com') assert conn is not None ``` -------------------------------- ### Set configuration via gNMI Source: https://context7.com/akarneliuk/pygnmi/llms.txt This Nornir task applies configuration changes to a device using gNMI. The 'update' parameter should be a list of tuples, each containing a path and its new value. The default encoding is 'json_ietf'. ```python def gnmi_set(task: Task, update: list, encoding: str = 'json_ietf') -> Result: """Set configuration via gNMI""" with gNMIclient( target=(task.host.hostname, task.host.port), username=task.host.username, password=task.host.password, insecure=True ) as gc: result = gc.set(update=update, encoding=encoding) return Result(host=task.host, result=result) ``` -------------------------------- ### Create gNMI Path from String Source: https://github.com/akarneliuk/pygnmi/blob/master/pygnmi.egg-info/SOURCES.txt Creates a gNMI Path object from a string representation. Supports various path formats. ```python def create_gnmi_path_from_string(path_str): return create_gnmi_path(path_str) ```