How to Use Python APIs for Cisco and Juniper Configs

You are currently viewing How to Use Python APIs for Cisco and Juniper Configs

How to Use Python APIs for Cisco and Juniper Configs

Image by: Field Engineer

Imagine managing five hundred core switches across three different continents. If you are still relying on manual SSH sessions and “copy-paste” CLI configurations, you aren’t just working hard—you are working dangerously. In modern hyperscale networks, manual configuration is the primary source of human error, which accounts for nearly 70% of network outages. To survive in this environment, you must leverage modern RESTCONF and NETCONF APIs using Python to manage multi-vendor Cisco and Juniper environments. This guide will transition you from traditional scripting to robust, structured, and scalable network automation, enabling you to treat your infrastructure as code.

The paradigm shift from CLI to programmatic automation

For decades, the Command Line Interface (CLI) was the undisputed king of network administration. We learned the specific syntax of IOS, Junos, or NX-OS, and we became experts at interpreting text-based outputs. However, the CLI was never designed for machines; it was designed for humans. When we try to automate CLI via “screen scraping” (parsing raw text strings with Regex), we create fragile scripts. A single firmware update that changes a single space or a word in a “show” command can break an entire automation pipeline.

The industry has moved toward model-driven programmability. Instead of parsing unstructured text, we now interact with structured data models, primarily using YANG (Yet Another Next Generation). By using YANG, the network device provides a strict blueprint of its capabilities. When you request a configuration via an API, you receive a predictable, machine-readable response in XML or JSON. This eliminates the guesswork and ensures that your Python scripts can interact with the device with mathematical precision.

By transitioning to API-driven management, you gain several critical advantages:

  • Idempotency: The ability to run the same script multiple times without changing the result beyond the initial application.
  • Scalability: Managing one hundred devices takes nearly the same effort as managing one.
  • Error Reduction: Structured data ensures that you aren’t sending “typo-ridden” commands to a production core router.
  • Version Control: You can store your configurations in Git, allowing for easy rollbacks and audit trails.

Understanding the core: netconf vs. restconf

As you begin your journey into modern automation, you will inevitably encounter two heavyweights: NETCONF and RESTCONF. While they both aim to solve the same problem—programmatically managing network devices—they do so using different philosophies and protocols. Understanding when to use which is vital for a successful multi-vendor strategy.

Netconf: The heavyweight champion

NETCONF (Network Configuration Protocol) is a highly robust protocol designed specifically for managing network devices. It typically runs over SSH and uses XML for both data encoding and transport. NETCONF is “transactional,” meaning it supports features like “candidate configurations” and “confirmed commit.” This is a lifesaver for administrators; you can send a batch of changes to a device, and if they don’t work, the device automatically rolls back the configuration to the last known good state after a timer expires.

Restconf: The web-friendly alternative

RESTCONF is a newer, lighter alternative that uses HTTP verbs (GET, POST, PUT, PATCH, DELETE) and is designed to be much more “web-like.” It uses JSON or XML and is significantly easier to interact with if you are already familiar with RESTful APIs used in web development. While it lacks the deep transactional capabilities of NETCONF, it is incredibly efficient for quick state retrieval and simple configuration tasks.

The following table summarizes the key differences to help you choose the right tool for your specific task:

Feature NETCONF RESTCONF
Transport Protocol SSH HTTP/HTTPS
Data Encoding XML XML or JSON
Configuration Model YANG YANG
Transaction Support High (Commit/Rollback) Limited
Complexity Higher (Learning Curve) Lower (Web-standard)

Setting up your Python environment and libraries

To start automating Cisco and Juniper devices, you need a clean Python environment. I highly recommend using a virtual environment to avoid dependency conflicts with your system’s Python installation. This is a fundamental best practice for any automation engineer.

The two essential libraries you will use are:

  1. ncclient: The industry standard for NETCONF. It handles the heavy lifting of SSH sessions and XML parsing for you.
  2. requests: The standard library for making HTTP calls, which we will use to interact with RESTCONF endpoints.

To get started, run the following commands in your terminal:

# Create a virtual environment
python3 -m venv network_env

# Activate the environment
source network_env/bin/activate

# Install the required libraries
pip install ncclient requests

Once your environment is set up, you should familiarize yourself with the concept of YANG models. You can explore models for Cisco IOS-XE or Juniper Junos on the IETF RFC documentation or via the device itself using specific commands. Understanding the hierarchy of these models is the difference between a script that works and a script that crashes your management plane.

Mastering authentication and data retrieval

Authentication is the first hurdle. When working with enterprise-grade equipment, simple username/password combinations are often insufficient. Most modern environments require SSH keys or even certificate-based authentication for NETCONF. For RESTCONF, you will likely deal with Bearer tokens or Basic Auth over HTTPS.

Let’s look at how we would retrieve operational data using Python. Instead of running show ip interface brief and parsing the text, we will request the structured data directly.

Example: Retrieving interface status via NETCONF (ncclient)

from ncclient import manager

# Device credentials
device_params = {
    'host': '192.168.1.1',
    'port': 830,
    'username': 'admin',
    'password': 'ecure_password',
    'hostkey_verify': False
}

# The XML filter to get interface information
filter_xml = """

    
        
    
    
        
    

"""

with manager.connect(**device_params) as m:
    response = m.get_config(netconf_source='running', filter=filter_xml)
    print(response.xml)

In this example, we are not just “getting text.” We are asking the device for a specific subtree of the YANG model. The response is a clean XML structure that can be instantly converted to a Python dictionary for processing. If you are working with Cisco devices, you might also want to explore Cisco DevNet for specific API documentation and sandboxes to test your code safely.

Applying transactional changes safely

This is where the real power—and the real danger—lies. Applying configurations programmatically can change the state of your entire network in milliseconds. If you make a mistake in a script, you could isolate an entire data center before you even realize what happened. To mitigate this, we rely on the “Candidate Configuration” and “Confirmed Commit” patterns.

In NETCONF, you don’t typically write directly to the “running” config. Instead, you follow this workflow:

  1. Lock the configuration: Prevents other users or processes from making changes simultaneously.
  2. Edit the candidate configuration: You upload your new settings to a “buffer” area on the device.
  3. Validate: Ask the device if the syntax of your new configuration is correct.
  4. Confirmed Commit: Apply the changes with a “rollback timer.” If you do not confirm the changes within a certain timeframe (e.g., 60 seconds), the device automatically reverts to the previous state.

“The single most important rule of network automation is: Always use a confirmed commit when making changes remotely. It is your only safety net against losing access to the device.”

For RESTCONF, you would use the `PATCH` method to update specific parts of a configuration without overwriting the entire configuration block. This is much safer than a `PUT` request, which replaces the entire resource. When building your Python logic, always implement a `try-except` block to catch connection errors or XML validation errors gracefully, ensuring your script doesn’t crash halfway through a multi-device update.

Managing multi-vendor environments efficiently

The ultimate goal for most network engineers is to abstract the vendor away. You want a script where you say “Set Interface GigabitEthernet1 to description Test” and the script knows whether to use Cisco syntax or Juniper syntax. This is achieved through abstraction layers.

To achieve this, you should avoid writing vendor-specific code in your main logic. Instead, use a design pattern like the Strategy Pattern. You create a generic “NetworkDevice” class, and then create subclasses for “CiscoDevice” and “JuniperDevice” that implement the specific API calls required for those vendors.

Another powerful tool for multi-vendor management is NAPALTI (Network Automation and Programmability Abstraction Layer with Python) or Nornir. These frameworks sit on top of your Python scripts to handle inventory management and parallel execution, allowing you to push changes to 50 Cisco and 50 Juniper routers simultaneously.

As you advance, consider integrating your Python scripts into a CI/CD pipeline (Continuous Integration/Continuous Deployment). This allows you to test your configuration changes in a virtual lab (like Cisco CML or Juniper vMX) before they ever touch production hardware. This level of maturity is what separates a “script kiddie” from a professional Network Automation Engineer. For more on advanced workflows, check out our advanced automation guides.

Frequently asked questions

What is the main difference between NETCONF and RESTCONF?

NETCONF is a robust, stateful protocol that uses SSH and XML, supporting transactional operations like ‘confirmed commit’ which is ideal for complex configuration changes. RESTCONF is a lightweight, stateless protocol using HTTP and JSON/XML, better suited for simple data retrieval and basic configuration updates.

Why should I use YANG models instead of CLI scraping?

YANG models provide a structured, standardized data schema. Unlike CLI scraping, which relies on parsing unpredictable text strings, YANG ensures that the data you receive is always in a predictable, machine-readable format (XML/JSON), making your Python scripts significantly more reliable and easier to maintain.

Is it safe to automate network configurations with Python?

Yes, provided you follow best practices. This includes using ‘confirmed commits’ via NETCONF, testing all scripts in a virtual lab environment, implementing error handling in your Python code, and using version control (like Git) to track configuration changes.

Do I need to learn XML or JSON?

You should understand both. NETCONF primarily uses XML, which is more verbose but highly structured for hierarchical data. RESTCONF supports both XML and JSON; JSON is often preferred for its simplicity and ease of use within Python applications.

Conclusion

Transitioning from manual CLI operations to API-driven automation is a fundamental step in modernizing your networking skillset. By mastering RESTCONF and NETCONF using Python, you move away from the fragile world of text parsing and into the robust world of model-driven programmability. You have learned the distinctions between these protocols, the importance of structured data models, how to set up a professional Python environment, and—most importantly—how to apply changes safely using transactional methods.

The journey from a traditional administrator to an automation engineer is not overnight. Start small: automate a single “show” command, then a single interface description, and slowly build toward multi-vendor, multi-device orchestration. The complexity of modern networks demands it. Start coding today, and turn your network into a programmable asset.