Network Automation with pyATS Framework

Comprehensive guide to implementing network test automation using Cisco's pyATS framework and Genie library for infrastructure validation.

pyats framework

Introduction

pyATS (Python Automated Test Systems) is Cisco's comprehensive test automation framework designed for network engineers and test developers. Combined with the Genie library (previously a separate package), pyATS provides powerful tools for network device testing, configuration validation, and automated verification workflows.

This framework bridges the gap between traditional network engineering and modern DevOps practices, enabling infrastructure-as-code approaches to network testing and validation.

Platform Support and Requirements

Python Version Compatibility

pyATS supports the following Python versions:

  • Python 3.7.x
  • Python 3.8.x
  • Python 3.9.x
  • Python 3.10.x

The framework is tested and validated on major operating systems including Linux, macOS, and Windows.

Supported Network Platforms

pyATS supports a wide range of network platforms through the Unicon library:

  • Cisco IOS/IOS-XE
  • Cisco NX-OS
  • Cisco IOS-XR
  • Cisco ASA
  • Juniper Junos
  • Arista EOS
  • And many more (full platform list)

Installation

Full Installation

Install pyATS with all libraries and dependencies:

pip install "pyats[full]"

This installation includes:

  • Core pyATS framework
  • Genie library for parsing and modeling
  • Unicon connection library
  • Common network parsers
  • Testing utilities

Testbed Configuration

Understanding Testbeds

A testbed file defines your network topology, device connections, and credentials. It serves as the inventory for your automation scripts, similar to Ansible's hosts file.

Creating Testbeds from Ansible Inventory

If you already use Ansible for configuration management, you can leverage existing inventory files to generate pyATS testbeds.

Ansible Playbook: run.yml

---
- name: Create Pyats Testbed From Ansible Inventory
  hosts: "{{ _devices }}"
  gather_facts: no
  vars:
    _devices:
      - cisco
 
  tasks:
 
  - name: Flatten Group Name To Device List
    set_fact:
      _testbed: '{{ _devices | map("extract", groups) | flatten | list }}'
 
  - name: Template Ansible Inventory Devices To Testbed.yml
    template:
      src: testbed.j2
      dest: testbed.yml

Jinja2 Template: templates/testbed.j2

devices:
{% for host in _testbed %}
  {{ hostvars[host]['inventory_hostname'] }}:
    connections:
      cli:
        ip: {{ hostvars[host]['ansible_host'] }}
        protocol: ssh
    credentials:
      default:
        password: {{ hostvars[inventory_hostname]['ansible_ssh_pass'] }}
        username: {{ hostvars[inventory_hostname]['ansible_user'] }}
      enable:
        password: {{ hostvars[inventory_hostname]['ansible_password'] }}
    os: {{ hostvars[inventory_hostname]['ansible_network_os'] }}
    type: {{ hostvars[inventory_hostname]['ansible_network_os'] }}
{% endfor %}

This approach ensures consistency between your Ansible configuration management and pyATS testing infrastructure.

Practical Implementation

Example: Retrieving Interface Bandwidth

This script demonstrates connecting to a network device, parsing command output, and extracting specific information:

from pyats.topology import loader
from genie.libs.parser.utils import get_parser_exclude
 
def main():
    # Load the testbed configuration
    testbed = loader.load('testbed.yaml')
 
    # Connect to the target device
    device = testbed.devices['r1']
    device.connect(log_stdout=False)
 
    # Execute and parse the command
    output = device.parse('show interfaces')
 
    # Access specific interface data
    interface = output['GigabitEthernet0/0']
 
    # Display interface information
    print(f"Interface: {interface['interface']}")
    print(f"Bandwidth: {interface['bandwidth']} Kbps")
 
    # Clean up connection
    device.disconnect()
 
if __name__ == '__main__':
    main()

Key Features Demonstrated

  1. Testbed Loading - Centralized device configuration management
  2. Connection Handling - Automated device connection with error handling
  3. Structured Parsing - Transform CLI output into Python dictionaries
  4. Data Extraction - Type-safe access to parsed data structures

Interactive Development

PyATS Shell Mode

For exploratory testing and development, pyATS provides an interactive shell:

pyats shell --testbed-file testbed.yaml

This launches an IPython environment with your testbed pre-loaded, enabling:

  • Interactive device connections
  • Real-time command execution
  • Immediate result inspection
  • Rapid prototyping of automation logic

Example Shell Workflow

# Load testbed (automatically done in shell mode)
>>> device = testbed.devices['router1']
 
# Connect to device
>>> device.connect()
 
# Learn device features
>>> interface_ops = device.learn('interface')
 
# Access learned data
>>> interface_ops.info['GigabitEthernet0/0']['bandwidth']
1000000

Advanced Use Cases

Network State Verification

Compare network state before and after changes:

# Capture baseline state
baseline = device.learn('ospf')
 
# Perform configuration change
# ... configuration commands ...
 
# Capture post-change state
current = device.learn('ospf')
 
# Compare states
diff = baseline.diff(current)

Multi-Device Operations

Execute operations across multiple devices:

for device_name, device in testbed.devices.items():
    device.connect()
    output = device.parse('show version')
    print(f"{device_name}: {output['version']['version']}")
    device.disconnect()

Integration Patterns

CI/CD Integration

pyATS integrates seamlessly with CI/CD pipelines:

  • Jenkins for automated test execution
  • GitLab CI for network validation on merge requests
  • GitHub Actions for infrastructure testing

Automated Testing Workflows

  1. Pre-deployment Validation - Verify network readiness
  2. Configuration Change Testing - Validate changes before production
  3. Continuous Monitoring - Regular state verification
  4. Regression Testing - Ensure changes don't break existing functionality

Lessons Learned

Parser Reliability

The Genie parser library covers hundreds of show commands across multiple platforms. However, always verify parser support for your specific platform and command before building production workflows.

Connection Management

Proper connection handling prevents resource leaks:

  • Always disconnect from devices in finally blocks
  • Use context managers when possible
  • Implement connection timeouts for unreachable devices

Testbed Management

Maintain separate testbed files for different environments (dev, staging, production) to prevent accidental production impacts during testing.

Resources and Documentation

Official Documentation

Parser Resources

Code Examples

Conclusion

pyATS transforms network testing from manual, error-prone processes into automated, repeatable workflows. By treating network infrastructure with the same testing rigor as application code, network engineers can implement continuous validation and catch issues before they impact production.

The framework's extensive parser library, multi-platform support, and Python-native design make it an essential tool for modern network automation and DevOps practices.