Inventory App

January 23, 2026 ยท View on GitHub

1. Basic Usage

1.1. Retrieve the configuration and status of an inventory device

The following examples demonstrate how to use the VideoIPath Automation Tool to retrieve the configuration and status of an inventory device. The retrieved device object includes attributes such as the device label, IP address, custom driver settings, and reachability status. This allows modifications to the device configuration and checking its status.

The device status does not update automatically; it must be refreshed manually.

A device can be uniquely identified using its device ID, which is generated by the VideoIPath system and cannot be modified. The device ID provides a definitive way to retrieve a specific device.

Alternatively, a device can be retrieved by its label or IP address. However, if multiple devices share the same label or IP address, the method raises an exception, listing the identifiers of all matching devices.

1.1.1 Retrieve a Device by its Unique Device ID

# Retrieve the latest configuration and status of a device from the server using its device ID.
inventory_device = app.inventory.get_device(device_id="device31")

print(inventory_device.configuration.label)   
# > GTW-161

print(inventory_device.configuration.address)   
# > 10.1.100.19

# Check if the device is reachable (the status does not update automatically).
if inventory_device.status:
    print(inventory_device.status.reachable)
    # > True

# Refresh the device status and print its updated reachability.
app.inventory.refresh_device_status(device=inventory_device)
if inventory_device.status:
    print(inventory_device.status.reachable)
    # > True

1.1.2 Retrieve a device by its label

device_by_label = app.inventory.get_device(label="GTW-161")
print(device_by_label.configuration.device_id)
# > device31

Note:

  • A device label is not necessarily unique. If multiple devices share the same label, the method raises an exception listing the identifiers of all matching devices.
  • There are three types of labels:
    • Factory Label: Assigned by VideoIPath (e.g., Arista Networks DCS-7050SX3-48YC8, NMOS, PowerCore Rev2 (710/11)).
    • User-Defined Label: Set by the user (e.g., GTW-161).
    • Canonical Name: Uses the factory label if no user-defined label is set.
  • By default, the get_device method searches using the canonical label.
  • To change the search type, set the label_search_mode parameter to:
    • "factory_label_only" (search by factory label)
    • "user_defined_label_only" (search by user-defined label)
device_by_label = app.inventory.get_device(label="GTW-161", label_search_mode="user_defined_label_only")
print(device_by_label.configuration.device_id)
# > device31

1.1.3 Retrieve a device by its IP address

device_by_ip = app.inventory.get_device(address="10.1.100.20")
print(device_by_ip.configuration.label)
# > Hello World

Note:

  • If multiple devices have the same IP address, the method will raise an exception containing the identifiers of the devices with the same IP address.
  • The method also considers alternative IP addresses.

1.2. Add a new device to the inventory

This example demonstrates how to add a new NMOS_multidevice device to the inventory using the VideoIPath Automation Tool. The new device is assigned the label Hello World and the IP address 10.1.100.20.

# Create a new NMOS_multidevice
new_inventory_device = app.inventory.create_device(driver="com.nevion.NMOS_multidevice-0.1.0")
new_inventory_device.configuration.label = "Hello World"
new_inventory_device.configuration.address = "10.1.100.20"
new_inventory_device.configuration.custom_settings.port = 5050

# Add the new device to the inventory and retrieve the created device configuration
online_device = app.inventory.add_device(device=new_inventory_device)

print(f"Device '{online_device.configuration.label}' with id '{online_device.configuration.device_id}' address '{online_device.configuration.address}' and NMOS port '{online_device.configuration.custom_settings.port}' created in Inventory!")
# > Device 'Hello World' with id 'device83' address '10.1.100.20' and NMOS port '5050' created in Inventory!

# Note: By default `label_check` and `address_check` are set to True.
# If the label or address already exists, the method will raise an exception.
app.inventory.add_device(device=new_inventory_device)
# > ValueError: ValueError: Device with label 'Hello World' already exists in Inventory: device83


1.3. Update the configuration of an existing device

This example demonstrates how to update the configuration of an inventory device using the VideoIPath Automation Tool. The device configuration is updated with a new label, IP address and NMOS port.

# Get the device with the user defined label "Hello World" from the inventory & set the custom settings type to get IntelliSense
device_to_update = app.inventory.get_device(
    label="Hello World",
    label_search_mode="user_defined_label_only",
    custom_settings_type="com.nevion.NMOS_multidevice-0.1.0",
)

# Update the device configuration
device_to_update.configuration.label = "Hello World Updated"
device_to_update.configuration.address = "10.1.100.21"
device_to_update.configuration.custom_settings.port = 8000

# Update the device in the inventory and retrieve the updated device configuration
updated_device = app.inventory.update_device(device=device_to_update)

print(
    f"Device '{updated_device.configuration.label}' with id '{updated_device.configuration.device_id}' address '{updated_device.configuration.address}' updated in Inventory!"
)
# > Device 'Hello World Updated' with id 'device83' address '10.1.100.21' updated in Inventory!

Note: If custom_settings_type is not set, everything is working, but there is no IntelliSense for the custom settings of the device.

1.4. Delete an existing device from the inventory

last_config = app.inventory.remove_device(device_id="device83")
if last_config:
    print(f"Device '{last_config.label}' with id '{last_config.device_id}' removed from Inventory!")
    # > Device 'Hello World Updated' with id 'device83' removed from Inventory!

Note:

  • The remove_device method deletes the device from the inventory. The last configuration of the device is returned. If the device does not exist, the method returns None.

1.5. Enable/Disable a device

enabled_device = app.inventory.enable_device("device52")
print(f"Device '{enabled_device.configuration.device_id}' enabled in Inventory ({enabled_device.configuration.active})!")
# > Device 'device52' enabled in Inventory (True)

disabled_device = app.inventory.disable_device("device52")
print(f"Device '{disabled_device.configuration.device_id}' disabled in Inventory ({disabled_device.configuration.active})!")
# > Device 'device52' disabled in Inventory (False)

2. Advanced Features and examples

2.1. Compare the configuration of two device objects

gtw_31 = app.inventory.get_device(label="GTW-31")
gtw_32 = app.inventory.get_device(label="GTW-32")

comparison = app.inventory.diff_device_configuration(gtw_31, gtw_32)

config_diff = comparison.configuration_diff

# Print with indentation
import json

print(json.dumps(config_diff.model_dump(mode="json"), indent=4))
# > {
#     "added": [],
#     "changed": [
#         {
#             "type": "value_changed",
#             "path": "root['config']['cinfo']['address']",
#             "old_value": "10.1.100.31",
#             "new_value": "10.1.100.32"
#         },
#         {
#             "type": "value_changed",
#             "path": "root['config']['desc']['label']",
#             "old_value": "GTW-31",
#             "new_value": "GTW-32"
#         },
#         {
#             "type": "value_changed",
#             "path": "root['config']['customSettings']['always_enable_rtp']",
#             "old_value": false,
#             "new_value": true
#         },
#         {
#             "type": "value_changed",
#             "path": "root['config']['customSettings']['indices_in_ids']",
#             "old_value": false,
#             "new_value": true
#         },
#         {
#             "type": "value_changed",
#             "path": "root['id']",
#             "old_value": "device52",
#             "new_value": "device53"
#         }
#     ],
#     "removed": []
# }

2.2. Dump and load the configuration of a device into a file

A device configuration can be dumped into a file and loaded back into the VideoIPath Automation Tool. This allows for easy comparison of the configuration of a device with a backup configuration.

2.2.1 Dump the configuration of a device into a file

gtw_31 = app.inventory.get_device(label="GTW-31")
gtw_31_config_dump = gtw_31.dump_configuration()

with open("gtw_31_config.json", "w") as file:
    file.write(json.dumps(gtw_31_config_dump, indent=4))

File content:

{
    "cinfoOverrides": {
        "snmp": {
            "useDefault": true,
            "id": "default"
        },
        "http": {
            "useDefault": false,
            "id": "default"
        }
    },
    "config": {
        "cinfo": {
            "protocols": {},
            "altAddresses": [],
            "altAddressesWithAuth": [],
            "auth": null,
            "http": {
                "https": false,
                "httpAuth": 0,
                "trustAllCertificates": false
            },
            "snmp": {
                "users": {},
                "security": {
                    "read": {
                        "level": 1,
                        "user": "",
                        "community": "public"
                    },
                    "write": {
                        "level": 1,
                        "user": "",
                        "community": "private"
                    }
                },
                "protocol": {
                    "preferredVersion": 1,
                    "retries": 1,
                    "maxRepetitions": 10,
                    "useGetBulk": true,
                    "timeout": 5000,
                    "localEngineId": ""
                }
            },
            "address": "10.1.100.31",
            "socketTimeout": null,
            "traps": {
                "trapDestinations": [],
                "trapType": "Trap",
                "user": "videoipath"
            }
        },
        "driver": {
            "name": "NMOS_multidevice",
            "organization": "com.nevion",
            "version": "0.1.0"
        },
        "desc": {
            "desc": "",
            "label": "GTW-31"
        },
        "customSettings": {
            "com.nevion.NMOS_multidevice.always_enable_rtp": false,
            "com.nevion.NMOS_multidevice.disable_rx_sdp": false,
            "com.nevion.NMOS_multidevice.disable_rx_sdp_with_null": true,
            "com.nevion.NMOS_multidevice.enable_bulk_config": false,
            "com.nevion.NMOS_multidevice.enable_experimental_alarm": false,
            "com.nevion.NMOS_multidevice.experimental_alarm_port": 0,
            "com.nevion.NMOS_multidevice.indices_in_ids": false,
            "com.nevion.NMOS_multidevice.port": 8080
        }
    },
    "meta": {},
    "active": true,
    "id": "device52"
}

2.2.2 Load the configuration of a device from a file and compare to the current configuration

In this example the configuration was changed in the GUI after the backup was made.

from videoipath_automation_tool.apps.inventory.model import InventoryDevice

with open("gtw_31_config.json", "r") as file:
    gtw_31_config = json.load(file)

gtw_31_from_backup = InventoryDevice.parse_configuration(gtw_31_config)

gtw_31_online_config = app.inventory.get_device(device_id=gtw_31_from_backup.configuration.device_id)

comparison = app.inventory.diff_device_configuration(gtw_31_from_backup, gtw_31_online_config)

print(json.dumps(comparison.configuration_diff.model_dump(mode="json"), indent=4))
#  > {
#     "added": [],
#     "changed": [
#         {
#             "type": "value_changed",
#             "path": "root['config']['customSettings']['enable_experimental_alarm']",
#             "old_value": false,
#             "new_value": true
#         }
#     ],
#     "removed": []
# }

2.3. Create a device from a discovered device

# Get the discovered devices
discovered_devices = app.inventory.get_discovered_devices()

# Print the ids, existence and driver of the discovered devices
for device in discovered_devices:
    print(
        f"Device ID: {device.id}, Corresponding driver exists: {device.exists}, Driver: {device.suggestedConfigs[0].driver}"
    )
    # > Device ID: OF-00:00:00:1e:08:0b:00:01, Corresponding driver exists: [], Driver: name='openflow' organization='com.nevion' version='0.0.1'
    # > Device ID: OF-00:00:00:1e:08:0f:00:02, Corresponding driver exists: ['device25', 'device47'], Driver: name='openflow' organization='com.nevion' version='0.0.1'

# Create a device object from a discovered device suggested configuration
device = app.inventory.create_device_from_discovered_device(
    discovered_device_id="OF-00:00:00:1e:08:0b:00:01", driver="com.nevion.openflow-0.0.1"
)

# Optionally, modify the device configuration
device.configuration.label = "My new eMerge"

# Add the device to the inventory
emerge_device = app.inventory.add_device(device)

2.4. Remove device id

2.4.1 Duplicate on another VideoIPath instance

# Get the device with the user defined label "Hello World" from the inventory
device_to_duplicate = app.inventory.get_device(
    label="Hello World",
    label_search_mode="user_defined_label_only",
    custom_settings_type="com.nevion.NMOS_multidevice-0.1.0",
)

# Remove the device id
device_to_duplicate.remove_device_id()

prod_app = VideoIPathApp(server_address="prod-vip.company.com", username="admin", password="admin")

# Add the device based on the duplicated device
duplicated_device = prod_app.inventory.add_device(device_to_duplicate)
print(f"Device '{duplicated_device.configuration.label}' with id '{duplicated_device.configuration.device_id}' duplicated in Inventory!")
# > Device 'Hello World' with id 'device1' duplicated in Inventory!")

2.4.2 Clone a device on the same VideoIPath instance

# Get the device with the user defined label "Hello World" from the inventory
device_to_clone = app.inventory.get_device(
    label="Hello World",
    label_search_mode="user_defined_label_only",
    custom_settings_type="com.nevion.NMOS_multidevice-0.1.0",
)

device_to_clone.configuration.label = "Hello World Cloned"
device_to_clone.configuration.address = "10.1.100.21"

# Remove the device id
device_to_clone.remove_device_id()

# Add the device based on the cloned device
cloned_device = app.inventory.add_device(device_to_clone)
print(f"Device '{cloned_device.configuration.label}' with id '{cloned_device.configuration.device_id}' cloned in Inventory!")
# > Device 'Hello World Cloned' with id 'device84' cloned in Inventory!")