Genie Libs SDK: Triggers and Verifications
Genie.libs.sdk is a sub-component of the Cisco pyATS and Genie framework, providing a rich library of pre-built 'Triggers' and 'Verifications'. These are reusable test cases and automation actions designed to facilitate rapid development, simplify test automation, and validate network device states. The library is actively maintained by Cisco Systems Inc., with frequent releases aligning with the broader pyATS/Genie ecosystem (typically monthly or bi-monthly major versions, currently at 26.3).
Common errors
-
ImportError: cannot import name 'SomePatternClass' from 'unicon.plugins.iosxe.csr1000v.patterns'
cause A mismatch in versions between pyATS/Genie core packages and specific Unicon plugins, or a refactoring/renaming of internal pattern classes in newer releases.fixEnsure all `pyats`, `genie`, and `unicon` packages and their respective plugins (`genie.libs.*`, `unicon.plugins.*`) are at compatible versions. A complete upgrade via `pip install --upgrade pyats genie --no-cache-dir` can often resolve this. -
TypeError: 'NoneType' object is not iterable
cause This generic Python error can occur when a `testbed.parse()` or a similar operation within Genie fails to retrieve data (e.g., device not connected, command failed) and returns `None`, which is then attempted to be iterated over or accessed like a dictionary.fixImplement robust error handling around device interactions. Verify device connectivity (`device.is_connected()`) and check the return values of parsing/learning APIs before proceeding with data manipulation. -
Exception: Terminal server information is not provided in the testbed YAML file for device '<device_name>'\nUnable to clear the console port line
cause Attempting to use a utility like `execute_clear_line` which requires `terminal_server` details in the testbed YAML, but these details are missing for the specified device.fixAdd the `peripherals.terminal_server` section to your device entry in the testbed YAML, specifying the terminal server details (e.g., `terminal_server: { my_term_server: [ 2001 ] }`).
Warnings
- breaking Python 3.6 support has been deprecated and removed in recent pyATS/Genie versions (e.g., v22.4). Users on Python 3.6 will encounter errors and must upgrade to Python 3.7+.
- gotcha When upgrading pyATS/Genie, users might encounter `ImportError` for specific patterns (e.g., `cannot import name 'Csr1000vPatterns'`). This often indicates a version mismatch between core pyATS/Genie and its plugins (like Unicon) or internal refactoring.
- gotcha Using `genie.libs.sdk` (and the broader Genie/pyATS framework) with multi-threaded applications like certain Nornir versions (e.g., Nornir 2.20 with >1 worker) has historically led to issues, particularly with the abstraction library loading layer.
Install
-
pip install genie -
pip install --upgrade genie.libs.sdk
Imports
- TriggerReload
from genie.libs.sdk.triggers.template.trigger_reload import TriggerReload
- TriggerShutNoShut
from genie.libs.sdk.triggers.interface import TriggerShutNoShut
- gRun
from genie.harness.main import gRun
- load
from genie.testbed import load
Quickstart
import os
from genie.testbed import load
from genie.harness.main import gRun
from genie.libs.sdk.triggers.template.trigger_reload import TriggerReload
# Create a dummy testbed.yaml for demonstration purposes
# In a real scenario, this would be a network device testbed file.
# Ensure your environment variables are set for device credentials.
# E.g., export PYATS_USERNAME=admin, export PYATS_PASSWORD=Cisco123
testbed_content = '''
devices:
R1:
os: iosxe
type: router
connections:
cli:
protocol: ssh
ip: 127.0.0.1
port: 2222 # Use a mock SSH server or a reachable device
credentials:
default:
username: ${PYATS_USERNAME}
password: ${PYATS_PASSWORD}
'''
with open('testbed.yaml', 'w') as f:
f.write(testbed_content)
# Set dummy environment variables if not already set
os.environ.setdefault('PYATS_USERNAME', 'mockuser')
os.environ.setdefault('PYATS_PASSWORD', 'mockpass')
def main():
# Load the testbed from the YAML file
testbed = load('testbed.yaml')
# Define the trigger to run
# In a real scenario, this would target a specific device and its OS
# For this example, we assume R1 is the 'uut' (unit under test) by default for TriggerReload
# A custom datafile might be needed for specific trigger parameters or device mappings
# Execute the trigger using gRun.
# The TriggerReload acts as a placeholder for demonstration.
# For a true reload, 'R1' would need to be a real device and reachable.
try:
print("\n--- Running TriggerReload on R1 ---")
gRun(testbed=testbed, trigger_uids=["TriggerReload"], trigger_datafile="""
extends: "%CALLABLE{genie.libs.sdk.genie_yamls.datafile(trigger)}"
TriggerReload:
devices:
R1:
command: 'reload'
"""
)
print("TriggerReload completed (or skipped if no real device was found).")
except Exception as e:
print(f"An error occurred during gRun: {e}")
if __name__ == '__main__':
main()