FastAPI Netmiko Wrapper + n8n: Turn network automation into n8n workflows
n8n for network automation -> without writing “automation glue"
If you’ve ever tried to connect Netmiko scripts to “everything else” (tickets, Slack, CMDB, approvals, schedules), you’ve probably ended up with a pile of cron jobs and bespoke glue code.
This project is a production-ready FastAPI wrapper around Netmiko that gives you a clean REST API for:
Device profiles (encrypted credentials, reusable by name)
Sync operations (get results immediately)
Async operations (enqueue work, poll task status/results)
Persistent sessions (connect once, run multiple operations without reconnecting)
Structured parsing for command output (TextFSM / TTP / Genie)
That makes it a great fit for n8n: you can build reliable workflows using standard HTTP Request nodes, and keep your network logic behind an internal API boundary.
GitHub repo: arpit-patel1/fastapi-wrapper-for-netmiko
What you get (API surface area)
Device profiles
POST /api/v1/devices/(create)GET /api/v1/devices/(list)GET /api/v1/devices/name/{device_name}(lookup)PUT /api/v1/devices/{device_id}(update)POST /api/v1/devices/test(connectivity test)
Sync ops
POST /api/v1/sync/send-commandPOST /api/v1/sync/send-configPOST /api/v1/sync/save-configPOST /api/v1/sync/scp-transfer
Async ops
POST /api/v1/async/send-commandPOST /api/v1/async/send-configPOST /api/v1/async/save-configPOST /api/v1/async/scp-transfer
Tasks
GET /api/v1/tasks/{task_id}(status)GET /api/v1/tasks/{task_id}/result(result)
Sessions
POST /api/v1/sessions/(create)POST /api/v1/sessions/command(run command over existing session)POST /api/v1/sessions/config(run config over existing session)DELETE /api/v1/sessions/{session_id}(close)
If you’re running locally, the docs are typically at:
http://localhost:8000/docs
Why this pairs well with n8n
n8n is excellent at:
Triggers (cron, webhook, GitHub, Jira, ServiceNow, email, etc.)
Approvals and branching logic
Retries and orchestration
Sending results (Slack/Teams/email)
This wrapper is excellent at:
Talking to network devices safely and consistently
Running commands/configs across one or many devices
Returning structured output for downstream automation
Put together, you get “network automation as workflows.”
n8n workflow patterns (copy/paste friendly)
Assume your wrapper is reachable at:
{{$env.NETMIKO_API_BASE}}(recommended in n8n), e.g.
http://netmiko-api:8000
In n8n, each of the following is typically an HTTP Request node with:
Method:
POST/GET/DELETEURL:
{{$env.NETMIKO_API_BASE}}/...Send Body: JSON
Pattern 1: “Run a show command” (sync)
Best for quick checks where you want the full output immediately.
Node: HTTP Request → POST /api/v1/sync/send-command
{
"device_profiles": ["router1", "switch1"],
"command": "show ip interface brief",
"use_textfsm": true
}
You can also run the exact same call with inline device credentials (no pre-created profile required):
{
"devices": [
{
"host": "192.168.1.10",
"port": 22,
"device_type": "cisco_ios",
"username": "admin",
"password": "password123",
"secret": "enable_secret"
}
],
"command": "show ip interface brief"
}
What n8n gets back:
A single response containing per-device results, including
success,output, anderror.If
use_textfsmis enabled, theoutputcan be structured data (when templates match).
Great for
Daily inventory snapshots
Interface/down alerts (run, parse, branch)
Compliance checks (run, evaluate, open ticket)
Pattern 2: “Run a change across many devices” (async + poll)
Best when you don’t want the workflow to block on a long-running operation.
Node A: HTTP Request → POST /api/v1/async/send-config
{
"devices": [
{
"host": "10.0.10.11",
"device_type": "cisco_ios",
"username": "admin",
"password": "password123"
},
{
"host": "10.0.10.12",
"device_type": "cisco_nxos",
"username": "admin",
"password": "password123"
},
{
"host": "10.0.10.13",
"device_type": "arista_eos",
"username": "admin",
"password": "password123"
}
],
"config_commands": [
"interface GigabitEthernet0/1",
"description Configured via n8n",
"no shutdown"
],
"error_pattern": "(Invalid|Error|Failed)"
}
This returns a task_id.
Node B: Wait
Add a short Wait node (e.g., 2–5 seconds).
Node C: HTTP Request → GET /api/v1/tasks/{{$json.task_id}}
Branch in n8n:
If
statusiscompletedorfailed→ fetch resultElse → loop back to Wait (with a max retry / timeout)
Node D: HTTP Request → GET /api/v1/tasks/{{$json.task_id}}/result
Use the task result to:
Post a Slack summary
Attach results to a ticket
Write to a database
Trigger a rollback workflow if failures occur
Pattern 3: “Interactive / multi-step change” (sessions)
Best when you’re doing multiple operations on the same device and want to avoid reconnect overhead.
Node A: Create session → POST /api/v1/sessions/
{
"device_profile": "router1",
"session_name": "n8n-change-window"
}
You’ll get session_id.
Node B: Command over session → POST /api/v1/sessions/command
{
"session_id": "{{$json.session_id}}",
"command": "show version"
}
Node C: Config over session → POST /api/v1/sessions/config
{
"session_id": "{{$json.session_id}}",
"config_commands": [
"logging host 10.10.10.10",
"service timestamps log datetime msec"
],
"error_pattern": "(Invalid|Error|Failed)"
}
Node D: Close session → DELETE /api/v1/sessions/{{$json.session_id}}
Sessions are great for workflows like:
Pre-check → change → post-check
“Show” → calculate diff → “config” → “save config”
Device profiles vs inline credentials (what I recommend for n8n)
Recommended (most common): Create device profiles once, then reference them by name from n8n using
device_profiles.You keep credentials out of the workflow payloads.
Credentials are stored encrypted by the service.
Useful for one-off jobs: Provide inline
devicesin the request body.Good for ad-hoc tasks or ephemeral targets.
This works for both
send-commandandsend-config(sync, async, and session create).
Mixed mode (handy in migrations): You can send both
device_profilesand inlinedevicesin the same request, and the service will run the operation across the combined device list.
Practical n8n ideas you can ship this week
Nightly config backup:
Cron trigger →
POST /api/v1/async/save-config→ poll tasks → store output in S3 → Slack summary
“Interface down” triage:
Webhook trigger from monitoring →
POST /api/v1/sync/send-commandwith TextFSM → branch by status → open ticket
Change window automation:
Manual approval → session create → pre-check → config → post-check → close session → create change record summary
Operational notes (keep it boring, keep it reliable)
Run the API inside your network (same place your SSH jump hosts live).
Limit access (CORS, firewall rules, reverse proxy, and consider adding auth in front).
Use async for bulk jobs so n8n isn’t waiting on long SSH operations.
Treat parsing as optional: enable TextFSM/TTP/Genie where it’s valuable, but keep raw output as a fallback.
If you want, I can also provide…
A ready-to-import n8n workflow JSON for:
Async config push + polling + Slack summary
Session-based pre/post checks
A “golden” set of HTTP nodes using
{{$env.NETMIKO_API_BASE}}and n8n credentials best practices

