Python读取JSON设备列表实现Netmiko SSH及过滤指定JSON字段
Let's break down your two problems and walk through practical solutions—these are super common when working with API-sourced device data and network automation!
Problem 1: Fixing TypeError: string indices must be integers When Connecting Devices
That error pops up because your script is trying to treat a string like a dictionary. Here's the typical scenario:
Your JSON file isn't a pure array of device dictionaries. Instead, it has an outer wrapper key (like
{"devices": [...]}), and you're accidentally iterating over the wrapper keys (strings like "devices") instead of the actual device list.
Solution: Extract the Device Array First
First, identify the outer key in your JSON that holds the device list (common names are devices, device_list, result, etc.). Then extract that array before looping with Netmiko.
Example corrected script:
import json from netmiko import ConnectHandler # Load your JSON file (or replace with API response parsing) with open("your_api_devices.json", "r") as f: api_response = json.load(f) # Extract the actual device array—replace "devices" with your JSON's outer key device_list = api_response.get("devices", []) # Now loop through the device dictionary array safely for device in device_list: try: conn = ConnectHandler( ip=device["ip"], username=device["username"], password=device["password"], device_type="cisco_ios" # Adjust to your device type (e.g., "juniper_junos") ) # Run your desired commands here print(f"Successfully connected to {device['ip']}") output = conn.send_command("show run | include hostname") print(output) conn.disconnect() except Exception as e: print(f"Connection failed for {device['ip']}: {str(e)}")
- Use
get()to avoid crashes if the outer key doesn't exist (it returns an empty list as a fallback). - Double-check your JSON structure with a tool like jq or a JSON viewer to confirm the outer key name.
Problem 2: Filtering JSON to Keep Only Required Fields
To generate a JSON file with just username, ip, and password, you'll need to iterate over the raw device data and build a new list of dictionaries with only those fields.
Solution: Build a Filtered Device List
You can do this with a simple loop or a concise list comprehension—both work, pick the one you find more readable.
Option 1: Explicit Loop (Great for clarity)
import json # Load raw API data with open("raw_api_response.json", "r") as f: raw_data = json.load(f) # Extract the device array first (same as Problem 1) raw_devices = raw_data.get("devices", []) # Filter to keep only the fields you need filtered_devices = [] for device in raw_devices: # Use get() to avoid KeyError if a field is missing in some devices filtered_device = { "ip": device.get("ip"), "username": device.get("username"), "password": device.get("password") } # Optional: Skip devices with missing required fields if all(filtered_device.values()): filtered_devices.append(filtered_device) # Save the filtered data to a new JSON file with open("filtered_devices.json", "w") as f: # Save as an object with a "devices" key, or just the array if preferred json.dump({"devices": filtered_devices}, f, indent=4)
Option 2: List Comprehension (More concise)
# Same setup as above, then: filtered_devices = [ {key: device[key] for key in ["ip", "username", "password"] if key in device} for device in raw_devices ] # Save the filtered list with open("filtered_devices.json", "w") as f: json.dump(filtered_devices, f, indent=4)
- The
if key in devicecheck ensures you don't get a KeyError if a device is missing a field. - Use
indent=4to make the output JSON human-readable.
内容的提问来源于stack exchange,提问作者chenoi

