[Day #19 Pyats Series] Introduction to Trigger APIs in pyATS using pyATS for Cisco [Python for Network Engineer]
Table of Contents
Introduction on the Key Points
Welcome to Day 19 of our “101 Days of pyATS (Vendor-Agnostic)” blog series!
Today, we’re unlocking the power of one of pyATS’ most enterprise-grade and automation-ready features—Trigger APIs.
In large-scale networks, routine tasks like rebooting a device, clearing interfaces, or toggling features for test purposes can become cumbersome. This is where Trigger APIs in pyATS come into play. These are pre-built, reusable Python classes that define structured actions with built-in verification steps—perfect for Python for Network Engineer use cases.
This article will help you understand:
- What Trigger APIs are in pyATS
- The modular structure behind a trigger
- A hands-on workflow using Cisco IOS-XE devices
- How to run triggers via
AEtest
orgenie run
- How these can integrate into CI/CD pipelines for automated regression and sanity testing
Whether you’re working in validation, DevOps, or automation QA, Triggers save time, reduce code duplication, and enforce structured validations.
Let’s dive in!
Topology Overview
To demonstrate trigger-based automation, we’ll use a simple topology:

We’ll run a TriggerReload on R1 and validate that it reloads successfully with expected configurations post-boot.
Later, you can extend this concept to dozens of routers in a production lab environment or a CI/CD pipeline.
Topology & Communications
Component | Details |
---|---|
Devices | Cisco IOS-XE (R1, R2) |
Connectivity | SSH |
Port | 22 |
Authentication | Username + Password |
pyATS Components | AEtest, TriggerReload, Testbed |
We assume that both devices are up and reachable from your automation server or local pyATS setup.
Workflow Script: Running TriggerReload on R1
We will use a built-in trigger class from Genie: TriggerReload
, which automatically handles:
- Pre-check: Save running config, collect baseline info
- Action: Send reload command to device
- Post-check: Reconnect and verify consistency
Here’s a simplified script:
#!/usr/bin/env python3 from genie.testbed import load from genie.libs.sdk.triggers.blitz.blitz import Blitz from genie.libs.sdk.triggers.template.trigger_reload import TriggerReload from pyats.aetest import Testcase, main # Load testbed testbed = load('testbed.yml') # Assign device device = testbed.devices['R1'] class TriggerTest(Testcase): @Testcase.setup def connect(self): device.connect(log_stdout=False) @Testcase.test def run_trigger(self): # Initialize trigger reload_trigger = TriggerReload() reload_trigger.device = device reload_trigger.mapping = reload_trigger.mapping # uses default # Run trigger manually reload_trigger.test() @Testcase.cleanup def disconnect(self): device.disconnect() if __name__ == '__main__': main()
This is one of the cleanest ways to integrate Cisco device reload testing in an automated, verifiable, and repeatable way.
Explanation by Line
Let’s break this script down line by line so your students can build mental models:
from genie.testbed import load
→ Loads your testbed file into a structured Python object.from genie.libs.sdk.triggers.template.trigger_reload import TriggerReload
→ Imports the reusable trigger class provided by Cisco Genie libraries.device = testbed.devices['R1']
→ Assigns the R1 device object for further operations.device.connect()
→ Opens an SSH session.TriggerReload()
→ Instantiates the trigger. You can modify it to add custom mappings if needed.reload_trigger.test()
→ Executes the full test: pre-check → reload → post-check.device.disconnect()
→ Graceful cleanup.
Triggers are written in reusable classes with built-in fail-handling, retry mechanisms, and rollback.
Sample testbed.yml File
testbed: name: trigger_lab credentials: default: username: admin password: cisco123 devices: R1: os: iosxe type: router connections: cli: protocol: ssh ip: 192.168.100.1 R2: os: iosxe type: router connections: cli: protocol: ssh ip: 192.168.100.2
Test your SSH access to these devices before running pyATS—especially for triggers like reload, which can break the session if not properly handled.
Post-validation CLI Screenshots (Real Expected Output)
After running the trigger script, your output should include something like:
+------------------------------------------------------------------------------+ | Trigger Reload | |------------------------------------------------------------------------------| | Pre-check: | | - Save config | | - Verify running OS | | Reloading device R1... | | Waiting for device to come back online... | | Reconnecting... | | Post-check: | | - Hostname consistency | | - Interface state verified | +------------------------------------------------------------------------------+
This log format will vary depending on verbosity, but shows the beauty of self-validating automation with Triggers.
FAQs
1. What are Trigger APIs in pyATS and why are they useful?
Trigger APIs are pre-built test logic templates provided by pyATS (via the genie.libs.sdk
) that automate common operational tasks such as:
- Interface flapping
- Reloading a device
- BGP neighbor reset
- Configuration removal and reapplication
These are useful for:
- Change management validation
- Network reliability testing
- Regression testing
With Triggers, you save time by not writing custom test logic from scratch.
2. How do Trigger APIs differ from writing my own Testcase
in pyATS?
Feature | Trigger API | Custom Testcase |
---|---|---|
Pre-built Logic | Yes | You must define manually |
Reusability | High (already written by Cisco) | Low (specific to your use case) |
Flexibility | Moderate (template driven) | High (full control) |
Time to Implement | Fast (few lines of config) | Slower (code everything) |
Triggers are great for common operations, while custom Testcases are for custom or niche scenarios.
3. How do I use a Trigger API in a test script?
Example:
from genie.libs.sdk.triggers.interface import TriggerShutNoShut class ShutNoShutInterface(TriggerShutNoShut): @aetest.test def test(self): super().test()
In the YAML file:
TriggerShutNoShut: interface: GigabitEthernet0/0
The trigger will:
- Learn interface state
- Shut it down
- Wait
- No shut it
- Verify restoration
It’s an end-to-end automation for validation use cases.
4. Are Trigger APIs Cisco-only or multi-vendor?
Currently, Trigger APIs are heavily Cisco-focused, especially for:
- IOS / IOS-XE / IOS-XR / NX-OS
- Protocol-level triggers (BGP, OSPF, interfaces)
However, you can:
- Write custom triggers for non-Cisco devices
- Extend existing ones using
genie.libs.sdk.triggers.template
- Combine with APIs/RESTCONF for modern platforms
Multi-vendor support is achievable, but requires extra effort.
5. How do I control which interfaces, protocols, or routes to target in a Trigger?
Each trigger supports learning logic from the device or you can hardcode values via YAML.
Example for BGP trigger:
TriggerResetBgpNeighbor: bgp_as: 65001 neighbor: 192.168.1.1
Or use learning:
TriggerResetBgpNeighbor: learn: true
Best practice: Let the Trigger learn automatically to make your scripts dynamic and environment-adaptive.
6. Where can I find the list of available Trigger APIs for Cisco?
Official documentation:
https://pubhub.devnetcloud.com/genie-docs/sdk/triggers/
You’ll find:
- Interface triggers
- Routing protocol triggers (BGP, OSPF, ISIS)
- Device-level triggers (reload, config replace)
- ACL and control plane triggers
You can also browse:
ls genie.libs.sdk.triggers.*
within Python or your IDE.
7. What are the prerequisites for using Trigger APIs effectively?
To use Trigger APIs in your lab or production sandbox, ensure:
- Valid pyATS testbed YAML with OS and credentials
- SSH/Console connectivity to devices
- pyATS installed with
genie.libs.sdk
- Proper test script structure using
aetest
Bonus: Use pyats clean
to pre-clean your devices if needed.
8. Can I customize a Trigger API for my specific use case?
Absolutely
You can:
- Subclass an existing trigger and override certain steps
- Add custom verification logic
- Inject environment variables via
CommonSetup
Example:
class MyCustomTrigger(TriggerShutNoShut): def verify_shut(self): # Add custom syslog parsing here pass
This way you keep the base logic but extend it for your enterprise or client-specific needs.
YouTube Link
Watch the Complete Python for Network Engineer: Introduction to Trigger APIs in pyATS using pyATS for Cisco Lab Demo & Explanation on our channel:
Join Our Training
If you’re loving these real-world automation workflows, it’s time to go beyond reading and start doing.
Trainer Sagar Dhawan is conducting a 3-Month Instructor-Led Training where we teach:
- Python for Network Engineers
- Ansible-based Configuration Management
- REST API + Netconf/YANG automation
- pyATS and Genie workflows
- Full Multi-Vendor Labs: Cisco, Arista, Palo Alto, FortiGate
- CI/CD & DevNet Career Prep
This course includes 100+ use cases like today’s Trigger-based workflows with complete lab access.
Check Full Course Outline & Register
Build your foundation in Python for Network Engineer roles with real-world scenarios, and elevate your career into the world of NetDevOps, DevNet, and beyond.
Enroll Now & Future‑Proof Your Career
Email: info@networkjourney.com
WhatsApp / Call: +91 97395 21088