Skip to content

Cisco Catalyst Center API Client Code Examples

This guide shows how to use the CiscoCatalystCenter client to interact with Cisco Catalyst Center APIs.

The wingpy Catalyst Center client is designed for seamless interaction with Cisco DNA Center's intent REST API. E.g. advanced device management, credential operations, and task polling.

Wingpy handles authentication, token refresh, logging, concurrency and error management for you.

  • The client raises UnsupportedMethodError for unsupported HTTP methods (e.g., PATCH).
  • You can call catalyst.authenticate() to force (re-)authentication.

The Basics - Connect and Get Devices

Environment Variables

You can set the environment variables in your shell to avoid hardcoding sensitive information in your code. Check out the FAQ section on Environment Variables for more details.

Connect to Catalyst Center
from wingpy import CiscoCatalystCenter

catalyst = CiscoCatalystCenter(
    base_url="https://catalyst.example.com", # (1)!
    username="...", # (2)!
    password="...", # (3)!
    verify=False,
)
  1. Environment variable:

    WINGPY_CATALYST_CENTER_BASE_URL
    
  2. Environment variable:

    WINGPY_CATALYST_CENTER_USERNAME
    
  3. Environment variable:

    WINGPY_CATALYST_CENTER_PASSWORD
    

Get all network devices
# list[dict]
devices = catalyst.get_all("/dna/intent/api/v1/network-device/")

for device in devices:
    print(device["id"], device["hostname"])

Get device by ID
device_id = "<your-device-id>"

# httpx.Response
response = catalyst.get(f"/dna/intent/api/v1/network-device/{device_id}")

print(response.json())

SNMP Credential Management Examples

As you may or may not know, the Catalyst Center REST API supports managing SNMP credentials.
With these examples we assume that you have set the environment variables for authentication as shown above.

When you create, delete or update SNMP credentials, Catalyst Center uses asynchronous tasks. This is true for many operations. That means you need to wait and poll for task completion, if you want to ensure the operation has completed successfully.

As Catalyst Center uses IDs internally, we will also need to get the credential ID based on the description.

To solve both, we will define some simple helper functions to make our code cleaner and easier to read.

Helper functions

Here's a poller for the purpose of waiting for task completion:

Helper function to poll for task completion
import time
import wingpy

def poll_task(catalyst: wingpy.CiscoCatalystCenter, task_id):
    while True:
        status = catalyst.get(f"/dna/intent/api/v1/tasks/{task_id}")
        if status.json()["response"].get("isError") or status.json()["response"].get("endTime"):
            break
        time.sleep(2)
    return status.json()["response"]["status"]

Often, you will need to translate a name to the corresponding internal ID used by the API. So, let's define a little helper function to get that ID based on the description of the credential:

Helper function to get existing credentials id
def get_credential_id(credentials, description):
    try:
        return [cred["id"] for cred in credentials if cred["description"] == description][0]
    except IndexError:
        raise ValueError(f"Credential with description '{description}' not found")

With these simple helpers in place, you can now create, update, and delete SNMP credentials as shown below.

Create, Update, and Delete SNMP Credentials

When creating SNMP credentials, a task is created that you need to poll for completion. We usually prefer to use the context manager (the with statement) to ensure proper cleanup of resources.

Create SNMP credentials
snmp = {
    "description": "Example SNMP",
    "readCommunity": "public",
}

# context manager
with wingpy.CiscoCatalystCenter(verify=False) as catalyst:
    rsp = catalyst.post(
        "/dna/intent/api/v2/global-credential",
        data={"snmpV2cRead": [snmp]},
    )

    task_id = rsp.json()["response"]["taskId"]
    # poll for task completion using the helper function
    status = poll_task(catalyst, task_id)

print(f"Task completed with status:\n {status}")

To update existing credentials, we first need to get the credential ID based on the description. Then we can issue the update request.

Update SNMP credentials
# context manager
with wingpy.CiscoCatalystCenter(verify=False) as catalyst:
    response = catalyst.get("/dna/intent/api/v2/global-credential").json()["response"]
    snmpv2c_read_credentials = response["snmpV2cRead"]

# get the SNMPv2c-read credential ID based on description
snmp_description = "Example SNMP Description"
snmp_id = get_credential_id(credentials=snmpv2c_read_credentials, description=snmp_description)

# define the update payload
update = {
    "instanceUuid": snmp_id,
    "description": "Example SNMP",
    "readCommunity": "public_updated",
}

with wingpy.CiscoCatalystCenter(verify=False) as catalyst:
    rsp = catalyst.put(
        "/dna/intent/api/v1/global-credential/snmpv2-read-community",
        data=update,
    )
    task_id = rsp.json()["response"]["taskId"]

    # poll for task completion using the helper function
    status = poll_task(catalyst, task_id)

print(f"Task completed with status:\n {status}")

Delete SNMP credentials
credential_path = "/dna/intent/api/v2/global-credential"
snmp_description = "Example SNMP"

with wingpy.CiscoCatalystCenter(verify=False) as catalyst:
    snmp_read = catalyst.get(credential_path).json()["response"]["snmpV2cRead"]
    snmp_id = get_credential_id(snmp_read, snmp_description)
    rsp = catalyst.delete(f"{credential_path}/{snmp_id}")
    print(rsp.status_code)

If the delete operation is successful, you should see a 202 status code printed. HTTP status code 202 indicates that the request has been accepted for processing, but the processing has not been completed yet. Again, you may want to poll for task completion if needed, but for delete operations it's often sufficient to just check the status code, unless you specifically need to confirm the deletion - e.g. in case you want to re-create a credential with the same description or name right after deletion.

Full Example Script

Complete SNMP Credential Management Example
import time
import wingpy

def poll_task(catalyst: wingpy.CiscoCatalystCenter, task_id):
    while True:
        status = catalyst.get(f"/dna/intent/api/v1/tasks/{task_id}")
        if status.json()["response"].get("isError") or status.json()["response"].get("endTime"):
            break
        time.sleep(2)
    return status.json()["response"]["status"]

def get_credential_id(credentials, description):
    try:
        return [cred["id"] for cred in credentials if cred["description"] == description][0]
    except IndexError:
        raise ValueError(f"Credential with description '{description}' not found")

snmp = {
    "description": "Example SNMP",
    "readCommunity": "public",
}

with wingpy.CiscoCatalystCenter(verify=False) as catalyst:
    # Create SNMP Credential
    rsp = catalyst.post(
        "/dna/intent/api/v2/global-credential",
        data={"snmpV2cRead": [snmp]},
    )
    task_id = rsp.json()["response"]["taskId"]
    status = poll_task(catalyst, task_id)
    print(f"Create Task completed with status:\n {status}")

    # Update SNMP Credential
    snmpv2c_read = catalyst.get("/dna/intent/api/v2/global-credential").json()["response"]["snmpV2cRead"]
    snmp_id = get_credential_id(credentials=snmpv2c_read, description=snmp["description"])

    update = {
        "instanceUuid": snmp_id,
        "description": "Example SNMP",
        "readCommunity": "public_updated",
    }

    rsp = catalyst.put(
        "/dna/intent/api/v1/global-credential/snmpv2-read-community",
        data=update,
    )
    task_id = rsp.json()["response"]["taskId"]
    status = poll_task(catalyst, task_id)
    print(f"Update Task completed with status:\n {status}")

    # Delete SNMP Credential
    rsp = catalyst.delete(f"/dna/intent/api/v2/global-credential/{snmp_id}")
    print(f"Delete response status code: {rsp.status_code}")
Expected Output
Create Task completed with status:
 SUCCESS
Update Task completed with status:
 SUCCESS
Delete response status code: 202