Nornir

Network automation framework for Python — parallel task execution across network device inventories. Nornir features: InitNornir for initialization with inventory (YAML/SimpleInventory), nr.run() for parallel task execution across all/filtered hosts, built-in tasks (netmiko_send_command, napalm_get), nornir-netmiko and nornir-napalm plugins, host/group filtering (nr.filter()), results processing (Result.result), failed_hosts tracking, task functions as plain Python, connection management (nornir.core.connections), and JSON/YAML output. Pure-Python alternative to Ansible for network automation — agent runs tasks on 100s of devices simultaneously.

Evaluated Mar 06, 2026 (0d ago) v3.x
Homepage ↗ Repo ↗ Developer Tools python nornir network-automation parallel inventory tasks netmiko napalm
⚙ Agent Friendliness
60
/ 100
Can an agent use this?
🔒 Security
77
/ 100
Is it safe for agents?
⚡ Reliability
78
/ 100
Does it work consistently?

Score Breakdown

⚙ Agent Friendliness

MCP Quality
--
Documentation
80
Error Messages
78
Auth Simplicity
75
Rate Limits
88

🔒 Security

TLS Enforcement
82
Auth Strength
78
Scope Granularity
72
Dep. Hygiene
82
Secret Handling
70

Network device credentials in inventory files — must use environment variables or secrets manager, never commit credentials to git. Parallel SSH to production devices can cause SSH daemon overload. Agent network automation requires change window and rollback plan. hosts.yaml should be gitignored if containing credentials.

⚡ Reliability

Uptime/SLA
78
Version Stability
80
Breaking Changes
78
Error Recovery
75
AF Security Reliability

Best When

Automating tasks across a fleet of network devices (10+ devices) in Python — Nornir provides inventory management, parallel execution, and task composability that Netmiko/NAPALM lack, with full Python flexibility that Ansible YAML lacks.

Avoid When

You need single-device automation (use Netmiko directly), GUI tooling, or your team prefers YAML playbooks (use Ansible).

Use Cases

  • Agent parallel device config — nr = InitNornir(config_file='config.yaml'); result = nr.run(task=netmiko_send_config, config_commands=['logging buffered 10000']); print_result(result) — push config to all devices simultaneously; agent configures 200 switches in parallel in seconds instead of minutes sequentially
  • Agent inventory-based automation — nr = InitNornir(config_file='config.yaml'); routers = nr.filter(type='router', site='NYC'); result = routers.run(task=napalm_get, getters=['interfaces', 'bgp_neighbors']) — filter devices by attributes; agent collects BGP state from all NYC routers simultaneously
  • Agent custom task function — def backup_config(task): output = task.run(task=netmiko_send_command, command_string='show running-config'); Path(f'backups/{task.host.name}.cfg').write_text(output.result) — Python function as Nornir task; agent runs backup_config on all devices in parallel; full Python flexibility inside tasks
  • Agent failed device handling — result = nr.run(task=deploy_acl); failed = result.failed_hosts; if failed: nr.filter(filter_func=lambda h: h.name in failed).run(task=deploy_acl, retry=True) — re-run failed hosts; agent automation handles partial failure gracefully; Nornir tracks which hosts succeeded and failed
  • Agent multi-vendor workflow — cisco = nr.filter(platform='cisco_ios'); juniper = nr.filter(platform='junos'); cisco.run(task=netmiko_send_config, config_commands=cisco_acl); juniper.run(task=napalm_configure, configuration=junos_config) — agent handles different vendors with appropriate tasks; one inventory, multiple execution strategies

Not For

  • Single device automation — Nornir's framework overhead isn't worth it for single device; use Netmiko directly
  • Non-network Python parallelism — Nornir is network-automation focused; for general parallel task execution use concurrent.futures or Ray
  • GUI or low-code network automation — Nornir is code-first; for low-code network automation use Ansible or NetBox

Interface

REST API
No
GraphQL
No
gRPC
No
MCP Server
No
SDK
Yes
Webhooks
No

Authentication

Methods: password ssh_key
OAuth: No Scopes: No

Device credentials in inventory YAML or via environment variables. Inventory supports password and SSH key auth per host or group. Secrets should come from environment not hardcoded in inventory.

Pricing

Model: open_source
Free tier: Yes
Requires CC: No

Nornir is Apache 2.0 licensed. Free for all use.

Agent Metadata

Pagination
none
Idempotent
Partial
Retry Guidance
Not documented

Known Gotchas

  • Plugins installed separately — nornir_netmiko and nornir_napalm are separate packages; pip install nornir alone gives empty task library; agent Nornir scripts must: pip install nornir nornir-netmiko nornir-napalm; import from correct module: from nornir_netmiko.tasks import netmiko_send_command
  • num_workers affects device SSH load — InitNornir(runner={'plugin': 'threaded', 'options': {'num_workers': 20}}) runs 20 parallel SSH sessions; too many workers overwhelms device SSH daemon (default max 10 sessions); agent automation must tune num_workers per device type and SSH capacity
  • result.failed_hosts doesn't re-run — result = nr.run(task=fn); result.failed_hosts returns dict of failed hosts; Nornir doesn't retry automatically; agent code must explicitly: failed_nr = nr.filter(filter_func=lambda h: h.name in result.failed_hosts); failed_nr.run(task=fn)
  • Inventory must use group defaults for credentials — hosts.yaml credentials override group.yaml defaults; if credentials in group 'all' and host has no credentials, host inherits; agent inventory architecture must use group 'all' defaults with per-host overrides for device-specific credentials
  • Connection plugin keeps connection open — Nornir caches SSH connections across task runs; task2 reuses task1's SSH session; if device reboots between tasks, cached connection fails; call task.host.close_connections() before tasks requiring fresh connection in agent workflows with device restarts
  • Task result.result may be None on exception — if task raises exception, result.exception has traceback but result.result is None; agent code checking result.result without checking result.failed first raises TypeError; always check 'if not result[host].failed:' before accessing result.result

Alternatives

Full Evaluation Report

Detailed scoring breakdown, competitive positioning, security analysis, and improvement recommendations for Nornir.

$99

Scores are editorial opinions as of 2026-03-06.

5215
Packages Evaluated
26151
Need Evaluation
173
Need Re-evaluation
Community Powered