Python for Network Engineers: A Guide to REST API Automation (2026)

You are currently viewing Python for Network Engineers: A Guide to REST API Automation (2026)

Python for Network Engineers: A Guide to REST API Automation (2026)

Image by: Christina Morillo

From manual CLI to automated infrastructure: Why the shift matters

Did you know that network engineers waste 30% of their workweek on repetitive CLI tasks? According to IEEE research, this manual approach creates bottlenecks in modern infrastructures. As networks scale beyond human-manageable limits, API-driven network management becomes essential. This transition isn’t just about learning Python—it’s about fundamentally changing how we interact with infrastructure. You’ll move from typing commands to programmatically controlling entire fleets, reducing errors by up to 70% according to Cisco’s automation studies. This article guides network engineers through practical Python implementation using Requests for REST APIs and Netmiko for SSH-based automation. You’ll learn concrete workflows for Cisco IOS-XE and Juniper Junos devices, handle authentication securely, and transform raw JSON into actionable insights—all while avoiding common pitfalls.

Understanding the building blocks: REST APIs and Python tools

REST APIs act as translators between your Python scripts and network devices. Unlike CLI’s text-based interaction, APIs use structured JSON or XML over HTTP(S). The Requests library simplifies sending HTTP requests, while Netmiko extends Python’s SSH capabilities for legacy devices. Consider these core components:

  • HTTP Methods: GET (retrieve data), POST (send commands), PUT/PATCH (update configurations)
  • Netmiko’s Multi-Vendor Support: Handles subtle differences in Cisco IOS, Juniper Junos, Arista EOS prompts
  • JSON as Lingua Franca: Lightweight data format returned by most modern APIs
Method CLI Equivalent API Advantage
show interfaces Text scraping Structured JSON with normalized keys
Configuration changes Manual sessions Atomic transactions with rollback
Bulk operations Sequential execution Parallel execution via async

For complex multi-vendor environments, combining Requests (for API-native devices) with Netmiko (for SSH fallback) creates a robust automation framework. Explore our automation tool comparisons to choose the right libraries for your stack.

Secure authentication workflows for Cisco and Juniper APIs

Never hardcode credentials in scripts! Modern API-driven network management requires secure authentication patterns. Cisco’s RESTCONF and Juniper’s Junos XML API use token-based auth. Here’s a safe workflow using Python’s Requests:

  1. Environment Variables: Store usernames/passwords in .env files (use python-dotenv package)
  2. Token Generation: For Cisco IOS-XE, POST credentials to /api/aaa/login to get a session token
  3. Certificate Verification: Always enable SSL verification with requests.get(verify=’/path/cert.pem’)

Cisco IOS-XE Example:

import requests
auth_url = "https://router1/apis/aaa/login"
response = requests.post(auth_url, json={"username": os.getenv('USER'), "password": os.getenv('PASS')}, verify=True)
session_token = response.json()['token']  # Use in headers: {'X-Auth-Token': session_token}

Juniper Junos Tip: For NETCONF over SSH with Netmiko, use SSH keys instead of passwords. Configure role-based access control (RBAC) to limit API user permissions using Juniper’s recommended practices.

Making your first API call: Retrieving device data step-by-step

Let’s fetch interface status from a Cisco IOS-XE device. Follow this workflow:

  1. Establish authenticated session (as shown above)
  2. Construct API endpoint URL (e.g., /restconf/data/Cisco-IOS-XE-interfaces-oper:interfaces)
  3. Set headers: Accept: application/yang-data+json
  4. Handle pagination for large datasets

Python Code Snippet:

headers = {
  "Accept": "application/yang-data+json",
  "X-Auth-Token": session_token
}
interfaces_url = "https://router1/restconf/data/Cisco-IOS-XE-interfaces-oper:interfaces"
response = requests.get(interfaces_url, headers=headers, verify=True)
if response.status_code == 200:
  interfaces = response.json()['Cisco-IOS-XE-interfaces-oper:interfaces']['interface']

For Juniper Junos, use the PyEZ library (jnpr.junos) to simplify operations. Retrieve BGP neighbors with:

from jnpr.junos import Device
with Device(host='router2', user=os.getenv('JUN_USER')) as dev:
  bgp_data = dev.rpc.get_bgp_neighbor_information()  # Returns XML (convert with xmltodict)

Always check HTTP status codes before processing data. 200=OK, 401=Unauthorized, 404=Invalid endpoint. Bookmark our status code guide for troubleshooting.

Mastering JSON data parsing and error handling

APIs return JSON nests that can overwhelm beginners. Consider this Cisco interface response snippet:

{
  "interface": [
    {
      "name": "GigabitEthernet0/0",
      "admin-status": "UP",
      "oper-status": "UP",
      "statistics": {
        "in-octets": 283745029,
        "in-errors": 12
      }
    }
  ]
}

Safe Parsing Techniques:

  • Use try/except blocks for missing keys: try: errors = interface['statistics']['in-errors']
  • Leverage Python’s .get() with defaults: errors = interface.get('statistics', {}).get('in-errors', 0)
  • Validate data with JSON Schema (jsonschema library)

When processing lists, always check if the API returns an object or array—Juniper sometimes changes structures based on item count. For complex data transforms, use jq-like syntax with jmespath:

import jmespath
down_ports = jmespath.search("interface[?oper-status=='DOWN'].name", response.json())

Automating configurations with Netmiko: Beyond REST APIs

Not all devices support APIs—that’s where Netmiko shines. It emulates CLI interactions over SSH while providing structured output. Example: Push ACL changes to legacy Cisco IOS devices.

from netmiko import ConnectHandler
device = {
  'device_type': 'cisco_ios',
  'host': '192.168.1.1',
  'username': os.getenv('SSH_USER'),
  'password': os.getenv('SSH_PASS')
}
commands = [
  'ip access-list extended PROTECT_SERVERS',
  'permit tcp any host 10.1.1.100 eq 443'
]
with ConnectHandler(**device) as conn:
  output = conn.send_config_set(commands)
  print(output)

Key Advantages:

  • Automatic session handling (no hung SSH sessions)
  • Configurable command timeouts
  • Pre/post-change validation hooks

Combine with NAPALM for vendor-neutral abstractions. Always use Netmiko’s commit() and rollback() methods for Juniper to avoid configuration locks.

Production-ready practices: Security, scalability, and error recovery

Transitioning to API-driven network management requires operational discipline. Implement these best practices:

  1. Credential Rotation: Integrate with HashiCorp Vault or AWS Secrets Manager
  2. Idempotent Scripts: Ensure repeat execution doesn’t cause side effects (use “if not” checks)
  3. Rate Limiting: Add 500ms delays between device calls with time.sleep(0.5)

For error recovery, build context managers that automatically:

  • Retry on connection failures (use tenacity library)
  • Validate configurations before deployment
  • Create rollback points via API (Cisco’s Configuration Archive)

Monitor automation performance with tools like Prometheus and always test scripts in lab environments. Remember:

Automation doesn’t eliminate errors—it amplifies them. Design for failure.

Start small with read-only operations before moving to critical config changes.

Frequently asked questions

Is API-driven network management replacing CLI entirely?

No—CLI remains essential for troubleshooting and legacy devices. APIs complement CLI by handling bulk operations and integrations. Most engineers use both: APIs for routine tasks, CLI for edge cases.

How do I handle API version changes in production scripts?

Pin to specific API versions in your URLs (e.g., /v1/interfaces). Monitor vendor deprecation notices and test new versions in staging. Use abstraction layers like NAPALM to minimize rewrite impacts.

What’s the biggest security risk in network automation?

Credential storage. Avoid plaintext passwords at all costs. Use encrypted secret managers and short-lived tokens. Implement network segmentation to restrict API access to trusted subnets.

Can I automate multi-vendor networks with Python?

Absolutely. Use vendor-agnostic libraries like NAPALM or create adapter layers that translate common functions (e.g., get_interfaces()) to vendor-specific API calls. Start with our cross-platform automation tutorial.

Conclusion

The shift from CLI to API-driven network management transforms network engineers into force multipliers. By mastering Python’s Requests and Netmiko libraries, you unlock scalable, error-resistant automation for Cisco, Juniper, and other platforms. Start with simple data retrieval, progress to configuration changes, and always prioritize security in your workflows. Remember: Automation isn’t about eliminating jobs—it’s about eliminating toil. Ready to accelerate your journey? Practice today by querying one device via API and share your results. For ongoing learning, explore our curated automation labs and join communities like NetDevOps on Slack. The future of networking is programmable—and you’re building it.