{"id":8485,"library":"pygnmi","title":"pygnmi: gNMI Client for Network Automation","description":"pygnmi (current version 0.8.15) is a pure Python gNMI client designed for managing network functions and collecting telemetry data. It provides an interface to interact with gNMI-enabled network devices, supporting operations like Get, Set, and Subscribe. The library is actively maintained with frequent minor releases, typically addressing bug fixes, performance improvements, and adding support for new gNMI features.","status":"active","version":"0.8.15","language":"en","source_language":"en","source_url":"https://github.com/akarneliuk/pygnmi","tags":["network automation","gnmi","telemetry","networking","grpc"],"install":[{"cmd":"pip install pygnmi","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Required for gRPC communication with gNMI targets.","package":"grpcio"},{"reason":"Underlying data serialization for gRPC messages.","package":"protobuf"}],"imports":[{"symbol":"gNMIclient","correct":"from pygnmi.client import gNMIclient"}],"quickstart":{"code":"import os\nfrom pygnmi.client import gNMIclient\n\n# Environment variables for connection details or default values\nGNMI_HOST = os.environ.get('GNMI_HOST', 'localhost')\nGNMI_PORT = int(os.environ.get('GNMI_PORT', '50051'))\nGNMI_USERNAME = os.environ.get('GNMI_USERNAME', 'admin')\nGNMI_PASSWORD = os.environ.get('GNMI_PASSWORD', 'admin')\n\n# Configure the gNMI target\ntarget = {\n    'addr': f'{GNMI_HOST}:{GNMI_PORT}',\n    'username': GNMI_USERNAME,\n    'password': GNMI_PASSWORD,\n    'insecure': True,  # Set to False for secure TLS connections and provide certificates\n    'encoding': 'JSON_IETF', # Or None to auto-detect based on device capabilities\n}\n\ntry:\n    with gNMIclient(target=target) as c:\n        # Get device capabilities\n        capabilities = c.capabilities()\n        print(\"\\n--- Device Capabilities ---\")\n        print(capabilities)\n\n        # Example: Get system hostname (path may vary by device/OS)\n        # Using a common path, adjust as needed for your device\n        hostname_path = ['/system/state/hostname']\n        get_response = c.get(path=hostname_path, encoding='JSON_IETF')\n        print(\"\\n--- Get Response (Hostname) ---\")\n        print(get_response)\n\n        # Example: Subscribe to an operational state (uncomment to run)\n        # subscription_paths = [\n        #    ('/interfaces/interface[name=eth0]/state/oper-status', True)\n        # ]\n        # print(\"\\n--- Subscribe (Streaming) ---\")\n        # for update in c.subscribe2(path_tuples=subscription_paths, subscribe_mode='STREAM', encoding='JSON_IETF'):\n        #    print(update)\n        #    # Add logic to break from loop after a few updates or a timeout\n\nexcept Exception as e:\n    print(f\"An error occurred: {e}\")\n    print(\"Please ensure the gNMI server is running and accessible with correct credentials.\")","lang":"python","description":"This quickstart demonstrates how to connect to a gNMI target, retrieve its capabilities, and perform a 'Get' operation for a specific path. It includes placeholders for host, port, and credentials, defaulting to common local development values or environment variables. An example for 'Subscribe' is provided but commented out."},"warnings":[{"fix":"Refactor telemetry code to use `pygnmi.client.gNMIclient.subscribe2()` for all new and existing telemetry collection.","message":"The `subscribe()` method is being deprecated in favor of `subscribe2()`. It is strongly recommended to migrate telemetry collection to `subscribe2()` for future compatibility and improved functionality.","severity":"deprecated","affected_versions":"v0.8.6+"},{"fix":"When creating `gNMIclient` or calling `get`/`subscribe2`, explicitly pass the `encoding` parameter (e.g., `encoding='JSON_IETF'`) if auto-detection is not sufficient or if migrating from pre-0.8.9 code.","message":"Prior to v0.8.9, `encoding` had a default value. From v0.8.9, `encoding` defaults to `None` and `capabilities()` is called on connect to auto-detect the supported encoding (with `json` and `json_ietf` preferred). Explicitly setting an encoding might be necessary if auto-detection doesn't pick the desired one or if upgrading from older versions.","severity":"gotcha","affected_versions":"v0.8.9+"},{"fix":"Upgrade `pygnmi` to v0.8.11 or later to resolve Juniper telemetry issues and ensure correct encoding handling.","message":"Version 0.8.11 fixed a telemetry break for Juniper devices caused by inconsistencies between `Capabilities()` communicated encodings and actual `Subscribe()` support. If experiencing issues with Juniper telemetry on versions prior to 0.8.11, upgrade immediately.","severity":"breaking","affected_versions":"pre-v0.8.11"},{"fix":"For production, set `insecure: False` in the `target` dictionary and provide `root_certificates`, `private_key`, and `certificate_chain` for proper TLS authentication.","message":"By default, `gNMIclient` uses `insecure=True`, which is suitable for development but not for production. For secure deployments, TLS must be configured.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Verify the `username` and `password` in the `target` dictionary. Ensure these credentials match what the gNMI server expects.","cause":"Incorrect username/password, or missing authentication details in the gNMI client configuration.","error":"_InactiveRpcError: <_InactiveRpcError of RPC that terminated with: status = StatusCode.UNAUTHENTICATED details = \"Authentication failed\""},{"fix":"Check the `addr` in the `target` dictionary for correct host and port. Ensure the gNMI server is running and network connectivity exists between the client and server.","cause":"The gNMI server is unreachable, incorrect host/port in the target address, or a firewall is blocking the connection.","error":"_InactiveRpcError: <_InactiveRpcError of RPC that terminated with: status = StatusCode.UNAVAILABLE details = \"Connect Failed\""},{"fix":"Verify the gNMI `path` is correct and exists on the target device. Add checks for `None` or empty responses (e.g., `if response and response.notification:`) before processing data.","cause":"Attempting to access elements of a gNMI response that is `None` or empty, often due to an invalid gNMI path or the requested data not existing on the device.","error":"TypeError: 'NoneType' object is not subscriptable"},{"fix":"Migrate from `subscribe()` to `subscribe2()` for all telemetry subscriptions, as `subscribe2()` is the recommended and actively developed method. Ensure all arguments are appropriate for `subscribe2()` and supported by your gNMI target.","cause":"Using arguments (like `qos`) that are only supported by the `subscribe2()` method with the older `subscribe()` method, or attempting to use a feature not supported by the target device.","error":"TypeError: subscribe() got an unexpected keyword argument 'qos'"}]}