TextFSM Templates for Network Devices, and Python wrapper for TextFSM's CliTable.
npx @tessl/cli install tessl/pypi-ntc-templates@8.0.0A comprehensive Python library providing TextFSM templates for parsing CLI output from network devices. The library includes hundreds of pre-built templates for various network device vendors and commands, along with a Python wrapper for TextFSM's CliTable functionality that converts unstructured CLI output into structured data formats.
pip install ntc-templatesfrom ntc_templates.parse import parse_outputImport the exception class for error handling:
from ntc_templates.parse import parse_output, ParsingExceptionfrom ntc_templates.parse import parse_output
# Example Cisco IOS "show vlan" output
vlan_output = """VLAN Name Status Ports
---- -------------------------------- --------- -------------------------------
1 default active Gi0/1
10 Management active
50 VLan50 active Fa0/1, Fa0/2, Fa0/3, Fa0/4, Fa0/5,
Fa0/6, Fa0/7, Fa0/8
"""
# Parse the output into structured data
result = parse_output(
platform="cisco_ios",
command="show vlan",
data=vlan_output
)
print(result)
# Output:
# [
# {
# 'vlan_id': '1',
# 'name': 'default',
# 'status': 'active',
# 'interfaces': ['Gi0/1']
# },
# {
# 'vlan_id': '10',
# 'name': 'Management',
# 'status': 'active',
# 'interfaces': []
# },
# {
# 'vlan_id': '50',
# 'name': 'VLan50',
# 'status': 'active',
# 'interfaces': ['Fa0/1', 'Fa0/2', 'Fa0/3', 'Fa0/4', 'Fa0/5', 'Fa0/6', 'Fa0/7', 'Fa0/8']
# }
# ]The library operates as a bridge between raw CLI output and structured data:
.textfsm) that define parsing rules for specific platform/command combinationsparse_output() function that automatically selects and applies the correct templateThe template-driven approach enables consistent parsing across hundreds of different network device commands without requiring custom parsing logic for each command.
Core functionality for parsing network device CLI output using TextFSM templates.
def parse_output(
platform=None,
command=None,
data=None,
template_dir=None,
try_fallback=False
):
"""
Return the structured data based on the output from a network device.
Args:
platform (str, optional): The platform the command was run on (e.g., 'cisco_ios')
command (str, optional): The command run on the platform (e.g., 'show int status')
data (str, optional): The output from running the command
template_dir (str, optional): The directory to look for TextFSM templates.
Defaults to setting of environment variable or default ntc-templates dir.
The specified directory must have a properly configured index file.
try_fallback (bool, optional): Whether to fallback to using the default template
directory upon failure with template_dir. Defaults to False.
Returns:
list: The TextFSM table entries as dictionaries with lowercase field names.
Each dictionary represents one row of parsed data.
Raises:
ParsingException: When TextFSM parsing fails or template cannot be found
ImportError: When TextFSM library is not available (especially on Windows)
"""Exception class for parsing errors.
class ParsingException(Exception):
"""
Error that is raised when TextFSM hits an 'Error' state.
This exception is raised when:
- TextFSM parsing fails due to template errors
- No matching template is found for the platform/command combination
- Template parsing encounters an unexpected data format
"""The library includes pre-built templates for common network device commands:
Templates are automatically selected based on platform and command matching using the index file.
ntc_templates/
├── templates/
│ ├── index # Template index file
│ ├── cisco_ios_show_vlan.textfsm
│ ├── cisco_ios_show_interfaces.textfsm
│ ├── arista_eos_show_interfaces.textfsm
│ └── ... (932 template files)You can use custom template directories:
from ntc_templates.parse import parse_output
# Use custom template directory
result = parse_output(
platform="custom_platform",
command="show custom",
data=raw_output,
template_dir="/path/to/custom/templates"
)
# Try custom templates first, fallback to built-in if needed
result = parse_output(
platform="cisco_ios",
command="show version",
data=raw_output,
template_dir="/path/to/custom/templates",
try_fallback=True
)Set the NTC_TEMPLATES_DIR environment variable to use a custom template directory globally:
export NTC_TEMPLATES_DIR="/path/to/custom/templates"When set, this becomes the default template directory for all parsing operations.
textfsm>=1.1.0from ntc_templates.parse import parse_output
interface_output = """
Interface Status Protocol
GigabitEthernet0/1 up up
GigabitEthernet0/2 down down
Serial0/0/0 up up
"""
result = parse_output(
platform="cisco_ios",
command="show interfaces status",
data=interface_output
)
for interface in result:
print(f"Interface {interface['interface']} is {interface['status']}")from ntc_templates.parse import parse_output, ParsingException
try:
result = parse_output(
platform="unknown_platform",
command="show version",
data=raw_output
)
except ParsingException as e:
print(f"Parsing failed: {e}")
except ImportError as e:
print(f"TextFSM not available: {e}")import os
from ntc_templates.parse import parse_output
# Ensure custom template directory exists with proper index file
custom_dir = "/path/to/custom/templates"
if os.path.exists(custom_dir):
result = parse_output(
platform="custom_device",
command="show custom command",
data=raw_output,
template_dir=custom_dir
)