A Python library for parsing and comparing hierarchical network device configurations
Project description
Network Configuration Parser
A Python library for parsing and analyzing hierarchical network device configurations with space-based indentation.
Features
- Parse network configurations from files or strings
- Build hierarchical parent-child relationships based on indentation
- Rich metadata for each configuration line (level, children, siblings, etc.)
- Search configurations with flexible filters
- Compare configurations to identify differences
- Support for any device with space-based indentation (Cisco, Arista, etc.)
Installation
From PyPI (Recommended)
pip install netconf-parser
From Source
git clone https://github.com/w4hf/netconf-parser.git
cd netconf-parser
pip install -e .
For Development
git clone https://github.com/w4hf/netconf-parser.git
cd netconf-parser
pip install -e ".[dev]"
Quick Start
Basic Usage
from netconf_parser import Conf
# Load from a string
config_text = """hostname router1
interface GigabitEthernet0/1
ip address 192.168.1.1 255.255.255.0
no shutdown
description WAN Link
"""
conf = Conf.from_string(config_text)
# Or load from a file
conf = Conf.from_file("config.txt")
# Access all lines
print(f"Total lines: {len(conf.lines)}")
# Access root-level lines
for line in conf.root_lines:
print(f"Root line: {line}")
Working with ConfLine Objects
Each line in the configuration is represented by a ConfLine object with rich metadata:
# Get a line
line = conf.lines[1] # interface line
# Access properties
print(f"Content: {line.content}") # ['interface', 'GigabitEthernet0/1']
print(f"Line number: {line.line_num}")
print(f"Level: {line.level}")
print(f"Has children: {line.has_children}")
print(f"Has parent: {line.has_parent}")
print(f"Is lone line: {line.lone_line}")
# Access relationships
print(f"Direct children: {line.direct_children_count}")
print(f"All descendants: {line.all_children_count}")
# Iterate through children
for child in line.children:
print(f" Child: {child}")
# Check siblings
for sibling in line.siblings:
print(f" Sibling: {sibling}")
Searching Configurations
Use search_line_start_with() to find specific lines:
from netconf_parser import search_line_start_with
# Find all interface lines at level 0
interfaces = search_line_start_with(conf, "interface", level=0)
# Find IP address lines under interfaces
ip_addresses = search_line_start_with(
conf,
"ip address",
level=1,
parent_start_with="interface"
)
# Find descriptions under a specific interface
descriptions = search_line_start_with(
conf,
"description",
level=1,
parent_start_with="interface GigabitEthernet0/1"
)
Comparing Configurations
Compare two configurations to identify differences:
from netconf_parser import compare_confs
# Load two configurations
ref_conf = Conf.from_file("baseline.txt")
new_conf = Conf.from_file("current.txt")
# Compare them
deleted, added, modified_root, modified_children = compare_confs(
ref_conf,
new_conf,
ignore_regex=r"^!" # Ignore comment lines
)
# Check deleted lines
print("Deleted lines:")
for line in deleted:
print(f" - {line}")
# Check added lines
print("Added lines:")
for line in added:
print(f" + {line}")
# Check modified root lines
print("Modified root lines:")
for line in modified_root:
print(f" ~ {line}")
# Check modified children
print("Modified children:")
for group in modified_children:
print(f" Group with parent: {group[0].parent}")
for line in group:
print(f" ~ {line}")
API Reference
Classes
Conf
Represents a complete network configuration.
Class Methods:
from_string(config_text: str) -> Conf: Create from a multiline stringfrom_file(file_path: str) -> Conf: Create from a file
Properties:
lines: List of all ConfLine objectsroot_lines: List of root-level ConfLine objects (level 0)
ConfLine
Represents a single configuration line with hierarchical properties.
Properties:
content: List of keywords (whitespace removed)line_num: Line number in the configurationlevel: Indentation depth (0 = root)has_children: Boolean indicating if line has childrenhas_parent: Boolean indicating if line has a parentparent: Reference to parent ConfLine (or None)children: List of direct child ConfLine objectssiblings: List of sibling ConfLine objectslone_line: True if line has no parent or childrendirect_children_count: Number of direct childrenall_children_count: Total number of descendantsdirect_children: List of direct children's contentall_children: List of all descendants' content
Functions
search_line_start_with()
Search for configuration lines matching specific criteria.
search_line_start_with(
conf: Conf,
search_string: str,
level: int,
parent_start_with: str | None = None
) -> list[ConfLine]
Parameters:
conf: The Conf object to searchsearch_string: String that lines must start withlevel: The indentation level to matchparent_start_with: Optional filter for parent line content
Returns: List of matching ConfLine objects
compare_confs()
Compare two configurations and identify differences.
compare_confs(
reference_conf: Conf,
compared_conf: Conf,
ignore_regex: str = ""
) -> tuple[list[ConfLine], list[ConfLine], list[ConfLine], list[list[ConfLine]]]
Parameters:
reference_conf: The baseline configurationcompared_conf: The configuration to compareignore_regex: Regular expression for lines to ignore
Returns: A tuple containing:
deleted_lines: Lines in reference but not in comparedadded_lines: Lines in compared but not in referencemodified_root_lines: Root lines with same start but different contentmodified_children: Groups of child lines with modifications
Running Tests
pytest tests/
To run with verbose output:
pytest -v tests/
To run a specific test file:
pytest tests/test_parser.py
Requirements
- Python 3.12+
- pytest 8.0+ (for testing)
License
This project is provided as-is for parsing network device configurations.
Examples
Example 1: Analyzing Interface Configuration
from netconf_parser import Conf, search_line_start_with
config = """
interface GigabitEthernet0/1
description WAN Link
ip address 192.168.1.1 255.255.255.0
no shutdown
interface GigabitEthernet0/2
description LAN Link
ip address 10.0.0.1 255.255.255.0
shutdown
"""
conf = Conf.from_string(config)
# Find all interfaces with "shutdown" configured
for interface in conf.root_lines:
if interface.content[0] == "interface":
has_no_shutdown = any(
" ".join(child.content) == "no shutdown"
for child in interface.children
)
has_shutdown = any(
" ".join(child.content) == "shutdown"
for child in interface.children
)
if has_shutdown and not has_no_shutdown:
print(f"Interface {interface.content[1]} is shutdown")
Example 2: Configuration Audit
from netconf_parser import Conf
config = """
interface GigabitEthernet0/1
ip address 192.168.1.1 255.255.255.0
interface GigabitEthernet0/2
ip address 10.0.0.1 255.255.255.0
description Configured
interface GigabitEthernet0/3
ip address 172.16.0.1 255.255.255.0
"""
conf = Conf.from_string(config)
# Find interfaces without descriptions
print("Interfaces without descriptions:")
for line in conf.root_lines:
if line.content[0] == "interface":
has_description = any(
child.content[0] == "description"
for child in line.children
)
if not has_description:
print(f" - {line.content[1]}")
Example 3: Configuration Diff Report
from netconf_parser import Conf, compare_confs
old_config = """hostname old-router
interface GigabitEthernet0/1
ip address 192.168.1.1 255.255.255.0"""
new_config = """hostname new-router
interface GigabitEthernet0/1
ip address 192.168.1.2 255.255.255.0"""
old_conf = Conf.from_string(old_config)
new_conf = Conf.from_string(new_config)
deleted, added, modified_root, modified_children = compare_confs(old_conf, new_conf)
print("Configuration Changes Report")
print("=" * 50)
print(f"Deleted lines: {len(deleted)}")
print(f"Added lines: {len(added)}")
print(f"Modified root lines: {len(modified_root)}")
print(f"Modified child groups: {len(modified_children)}")
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file netconf_parser-1.0.0.tar.gz.
File metadata
- Download URL: netconf_parser-1.0.0.tar.gz
- Upload date:
- Size: 17.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ea59916e0937a2baf724fa3f8ece699c3cd1acbb3d035901f34bfea6df9452bd
|
|
| MD5 |
87eb665617f518ed9ce4254f3366c02a
|
|
| BLAKE2b-256 |
8d495f21bde8c0caad7d460c752eddfe7ee84d7e54221679121ddce12237ce9c
|
File details
Details for the file netconf_parser-1.0.0-py3-none-any.whl.
File metadata
- Download URL: netconf_parser-1.0.0-py3-none-any.whl
- Upload date:
- Size: 10.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9edee4a29944250d1a9421533f040ad6967dfe7bd798c52e8bc4bbd44887c02e
|
|
| MD5 |
87ca8ca4ccb0b173b84c4787f392864e
|
|
| BLAKE2b-256 |
2eb8888947949b4ae3b13f28a1debdcdead083d686457fd5641f3b912aa400d5
|