NetConfigPulse
NetConfigPulse is an open source Python package and CLI for network device configuration backup. It connects to routers and switches over SSH, runs vendor-specific collection commands, saves versioned backup files, and generates diffs against previous runs. Maintained by 21Vianet.
Quick Start
Install the released package from PyPI:
pip install NetConfigPulse
netconfigpulse --help
Use the CLI with your own YAML files, or clone the repository and start from the sample configuration:
netconfigpulse validate \
--inventory config/devices.example.yaml \
--commands config/commands.default.yaml \
--credentials config/credentials.example.yaml \
--config config/runtime.example.yaml
This validates the example configuration without connecting to any device. Use
backup only after replacing the example devices and credentials with real
values.
Installation
From PyPI:
pip install NetConfigPulse
netconfigpulse --help
The PyPI package includes both the netconfigpulse console command and the
Python library API. To run the example configuration files from this repository,
clone the repository or copy the config/ directory, then run:
netconfigpulse validate \
--inventory config/devices.example.yaml \
--commands config/commands.default.yaml \
--credentials config/credentials.example.yaml \
--config config/runtime.example.yaml
CLI Usage
Three subcommands: validate, backup, import-csv.
After installation, both python -m netconfigpulse ... and the console command
netconfigpulse ... are supported.
validate
Loads and validates all config files. Reports errors without connecting to any devices.
python -m netconfigpulse validate \
--inventory config/devices.example.yaml \
--commands config/commands.default.yaml \
--credentials config/credentials.example.yaml \
--config config/runtime.example.yaml
backup
Runs the backup workflow: connect to devices, execute commands, save output, generate diffs.
python -m netconfigpulse backup \
--inventory config/devices.example.yaml \
--commands config/commands.default.yaml \
--credentials config/credentials.example.yaml \
--config config/runtime.example.yaml
All flags:
| Flag | Required | Default | Description |
|---|---|---|---|
--inventory |
yes | — | Path to device inventory YAML |
--commands |
yes | — | Path to vendor command catalog YAML |
--credentials |
no | — | Path to credentials YAML (can also use env vars, see below) |
--config |
no | — | Path to runtime config YAML |
--device |
no | — | Filter: backup a single device by name |
--tag |
no | — | Filter: backup only devices with this tag |
--group |
no | — | Filter: backup only devices in this group |
--output |
no | text |
Output format: text or json |
--concurrency |
no | 10 |
Max parallel SSH sessions |
--backup-root |
no | backups |
Root directory for backup files |
When --config is provided, values in the runtime config file take precedence
over the --backup-root and --concurrency command-line defaults.
import-csv
Imports a vendor command catalog from CSV and writes it as YAML.
python -m netconfigpulse import-csv \
--input device_cli_command.csv \
--output config/commands.default.yaml
Exit codes
0— all devices succeeded1— the entire run failed (no devices succeeded)2— partial failure (some succeeded, some failed)
End-to-End Example
Input files
config/devices.example.yaml
devices:
- name: edge-r1
host: 192.0.2.10
vendor: cisco_ios
tags:
- production
- edge
group: core
config/commands.default.yaml
vendors:
cisco_ios:
backup:
- terminal length 0
- show running
config/credentials.example.yaml
defaults:
username: backup-user
password: change-me
config/runtime.example.yaml
backup_root: backups
concurrency: 10
min_backup_size_bytes: 2000
backup_retry_attempts: 3
backup_retry_delay_seconds: 10
Run
python -m netconfigpulse backup \
--inventory config/devices.example.yaml \
--commands config/commands.default.yaml \
--credentials config/credentials.example.yaml \
--config config/runtime.example.yaml
Text output
Backed up 1 device: 1 succeeded, 0 failed, 0 warned, 1 changed.
JSON output
Pass --output json to get machine-readable output:
{
"total_devices": 1,
"success_count": 1,
"failed_count": 0,
"warning_count": 0,
"changed_devices": 1,
"unchanged_devices": 0,
"results": [
{
"device_name": "edge-r1",
"status": "success",
"file_path": "backups/2026-04-21/edge-r1/edge-r1_020202.cfg",
"diff_file_path": "backups/2026-04-21/diff/edge-r1/edge-r1_020202_diff.cfg",
"has_changes": true,
"backup_size": 12345,
"warnings": [],
"error": null
}
]
}
Python Library API
NetConfigPulse can also be used directly as a Python library.
Minimal example
from pathlib import Path
from netconfigpulse import load_commands, load_credentials, load_inventory, run_backup
from netconfigpulse.models.config import BackupOptions
devices = load_inventory("config/devices.example.yaml")
commands = load_commands("config/commands.default.yaml")
credentials = load_credentials("config/credentials.example.yaml")
result = run_backup(
devices=devices,
command_catalog=commands,
credentials=credentials,
options=BackupOptions(
backup_root=Path("backups"),
concurrency=10,
),
)
# result is a dataclass, not JSON — access fields directly
print(result.total_devices)
print(result.success_count)
print(result.failed_count)
# to convert to dict / JSON:
from dataclasses import asdict
import json
print(json.dumps(asdict(result), indent=2))
Available functions
| Function | Purpose |
|---|---|
load_inventory(path) |
Read device list from YAML |
load_commands(path) |
Read vendor command catalog from YAML |
load_credentials(path) |
Read credentials from YAML (also picks up env vars) |
run_backup(...) |
Run the full backup workflow (connect, collect, save, diff) |
generate_diff(current, previous) |
Produce a unified diff between two backup texts |
filter_dynamic_content(text) |
Replace timestamps and uptime with placeholders to avoid false diffs |
Result shape
run_backup(...) returns a BackupRunResult with aggregated counters and per-device entries.
Top-level fields:
total_devices: intsuccess_count: intfailed_count: intwarning_count: intchanged_devices: intunchanged_devices: intresults: list[DeviceBackupResult]
Each DeviceBackupResult includes:
device_name: strstatus: strfile_path: str | Nonediff_file_path: str | Nonehas_changes: boolbackup_size: int | Nonewarnings: list[str]error: str | None
Return example
BackupRunResult(
total_devices=1,
success_count=1,
failed_count=0,
warning_count=0,
changed_devices=1,
unchanged_devices=0,
results=[
DeviceBackupResult(
device_name="edge-r1",
status="success",
file_path="backups/2026-04-21/edge-r1/edge-r1_020202.cfg",
diff_file_path="backups/2026-04-21/diff/edge-r1/edge-r1_020202_diff.cfg",
has_changes=True,
backup_size=12345,
warnings=[],
error=None,
)
],
)
Configuration Files
config/devices.example.yaml— device inventoryconfig/commands.default.yaml— full vendor command catalogconfig/commands.minimal.yaml— smaller starter sampleconfig/credentials.example.yaml— credentials (can also be provided via env vars)config/runtime.example.yaml— runtime options (backup root, concurrency, backup-size warning threshold, retry policy)
Credentials can be provided via YAML file or environment variables. Env vars override YAML defaults:
NETCONFIGPULSE_DEFAULT_USERNAMENETCONFIGPULSE_DEFAULT_PASSWORDNETCONFIGPULSE_DEFAULT_SECRET
The --credentials flag is optional. If omitted, credentials come from env vars only.
min_backup_size_bytes warns when a text backup is smaller than the configured
threshold, which helps catch truncated or prompt-only backup files. Set it to
0 to disable this warning. Binary backup output is written as bytes and does
not use the text-size warning.
backup_retry_attempts and backup_retry_delay_seconds retry transient SSH
failures, empty backup output, and text backups that are below the minimum-size
threshold before the run records the final result.
Project Layout
netconfigpulse/
cli/ # argparse entry point
core/ # backup engine orchestrator
loaders/ # YAML/CSV parsers
models/ # dataclasses (Device, BackupOptions, results, etc.)
transports/ssh/ # netmiko-based SSH runner
diffing/ # unified diff generator
filters/ # dynamic content filters (timestamps, uptime)
output/ # text and JSON renderers
config/ # default and example configuration files
scripts/
tests/
docs/
Integration Scenarios
- Call the CLI from CI/CD pipelines or cron schedulers
- Consume machine-readable output via
--output json - Embed the Python package into a larger internal service
Governance
NetConfigPulse is maintained by 21Vianet as the lead steward. External contributions are welcome, while roadmap direction, release management, and future commercial packaging remain under maintainer control.
Release files for NetConfigPulse 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| netconfigpulse-0.1.1.tar.gz | 21.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| netconfigpulse-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 43.9 kB
Release files / netconfigpulse-0.1.1.tar.gz
| Download URL | netconfigpulse-0.1.1.tar.gz |
|---|---|
| Size | 21.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
64f145efedba65ec5c6c3be8ff5926edbce52d659cfa6f286a5c4f1a307f52bc
|
|
BLAKE2b-256 checksum How to use checksums |
4aec53e8a5766c33008d3628748dccda904a858d6e814500fb141b667061f0a7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Release files / netconfigpulse-0.1.1-py3-none-any.whl
| Download URL | netconfigpulse-0.1.1-py3-none-any.whl |
|---|---|
| Size | 22.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ab47e6f3e7dcd3f7d9e8f4b7548ec4be4c98ee556eddd2205e1ba90aa408d8a0
|
|
BLAKE2b-256 checksum How to use checksums |
f5a85270a6f2b68188af09d43c2fd949b05711abb0bf0ac0a686332273f6f432
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|