šŸ’¼ Practical API Operations

Real-World Code Examples for Cisco Platforms

šŸ“” 3.9.a Obtain List of Network Devices

Overview

Each Cisco platform provides APIs to retrieve network device inventory. Below are working examples for Meraki, DNA Center, ACI, SD-WAN, and NSO.

1. Meraki - Get Network Devices

Meraki Dashboard API - List Devices

šŸ“‹ Requirements:
  • Meraki API key (from Dashboard)
  • Organization ID
  • Network ID (optional, for specific network)
#!/usr/bin/env python3
"""
Meraki - Get Network Devices
Using Meraki Dashboard API SDK
"""

import meraki

# Initialize Meraki Dashboard API
API_KEY = "your_meraki_api_key_here"
dashboard = meraki.DashboardAPI(API_KEY, print_console=False)

def get_organizations():
    """Get all organizations"""
    try:
        orgs = dashboard.organizations.getOrganizations()
        print("="*70)
        print("MERAKI ORGANIZATIONS")
        print("="*70)
        for org in orgs:
            print(f"Org ID: {org['id']}")
            print(f"Name: {org['name']}\n")
        return orgs
    except Exception as e:
        print(f"āŒ Error: {e}")
        return []

def get_all_devices_in_org(org_id):
    """Get all devices across all networks in organization"""
    try:
        devices = dashboard.organizations.getOrganizationDevices(org_id)
        
        print("\n" + "="*70)
        print(f"ALL DEVICES IN ORGANIZATION: {org_id}")
        print("="*70)
        print(f"\nāœ… Found {len(devices)} device(s)\n")
        
        for device in devices:
            print(f"Name: {device.get('name', 'Unnamed')}")
            print(f"  Model: {device['model']}")
            print(f"  Serial: {device['serial']}")
            print(f"  MAC: {device.get('mac', 'N/A')}")
            print(f"  Network ID: {device.get('networkId', 'N/A')}")
            print(f"  Status: {device.get('status', 'Unknown')}")
            print(f"  Public IP: {device.get('publicIp', 'N/A')}")
            print(f"  Firmware: {device.get('firmware', 'N/A')}")
            print("-" * 70)
        
        return devices
    except Exception as e:
        print(f"āŒ Error: {e}")
        return []

def get_devices_by_network(network_id):
    """Get devices in specific network"""
    try:
        devices = dashboard.networks.getNetworkDevices(network_id)
        
        print("\n" + "="*70)
        print(f"DEVICES IN NETWORK: {network_id}")
        print("="*70)
        
        for device in devices:
            print(f"\n{device.get('name', 'Unnamed')} ({device['model']})")
            print(f"  Serial: {device['serial']}")
            print(f"  LAN IP: {device.get('lanIp', 'N/A')}")
            print(f"  Tags: {', '.join(device.get('tags', []))}")
        
        return devices
    except Exception as e:
        print(f"āŒ Error: {e}")
        return []

def get_device_statuses(org_id):
    """Get device status information"""
    try:
        statuses = dashboard.organizations.getOrganizationDevicesStatuses(org_id)
        
        print("\n" + "="*70)
        print("DEVICE STATUS SUMMARY")
        print("="*70)
        
        online_count = sum(1 for d in statuses if d.get('status') == 'online')
        offline_count = sum(1 for d in statuses if d.get('status') == 'offline')
        
        print(f"\nāœ… Online: {online_count}")
        print(f"āŒ Offline: {offline_count}")
        print(f"šŸ“Š Total: {len(statuses)}")
        
        return statuses
    except Exception as e:
        print(f"āŒ Error: {e}")
        return []

# Main execution
if __name__ == "__main__":
    # Get organizations
    orgs = get_organizations()
    
    if orgs:
        org_id = orgs[0]['id']
        
        # Get all devices in organization
        devices = get_all_devices_in_org(org_id)
        
        # Get device statuses
        get_device_statuses(org_id)

2. DNA Center - Get Network Devices

DNA Center Intent API - List Devices

#!/usr/bin/env python3
"""
DNA Center - Get Network Devices
Using DNA Center SDK
"""

from dnacentersdk import DNACenterAPI

# Initialize DNA Center API
dnac = DNACenterAPI(
    username="admin",
    password="password",
    base_url="https://sandboxdnac.cisco.com",
    version='2.3.3.0',
    verify=False
)

def get_all_devices():
    """Get all network devices"""
    try:
        devices = dnac.devices.get_device_list()
        
        print("="*70)
        print("DNA CENTER - NETWORK DEVICES")
        print("="*70)
        print(f"\nāœ… Found {len(devices.response)} device(s)\n")
        
        for device in devices.response:
            print(f"Hostname: {device.hostname}")
            print(f"  IP Address: {device.managementIpAddress}")
            print(f"  Device Type: {device.type}")
            print(f"  Platform ID: {device.platformId}")
            print(f"  Software: {device.softwareVersion}")
            print(f"  Serial: {device.serialNumber}")
            print(f"  Role: {device.role}")
            print(f"  Reachability: {device.reachabilityStatus}")
            print(f"  Family: {device.family}")
            print("-" * 70)
        
        return devices.response
    except Exception as e:
        print(f"āŒ Error: {e}")
        return []

def get_devices_by_family(family):
    """Get devices by family (Switches, Routers, etc.)"""
    try:
        devices = dnac.devices.get_device_list(family=family)
        
        print(f"\nāœ… {family} Devices:")
        for device in devices.response:
            print(f"  - {device.hostname} ({device.platformId})")
        
        return devices.response
    except Exception as e:
        print(f"āŒ Error: {e}")
        return []

def get_devices_by_role(role):
    """Get devices by role (ACCESS, CORE, DISTRIBUTION)"""
    try:
        devices = dnac.devices.get_device_list(role=role)
        
        print(f"\nāœ… {role} Role Devices:")
        for device in devices.response:
            print(f"  - {device.hostname} at {device.managementIpAddress}")
        
        return devices.response
    except Exception as e:
        print(f"āŒ Error: {e}")
        return []

def get_device_by_ip(ip_address):
    """Get specific device by IP"""
    try:
        device = dnac.devices.get_device_list(
            managementIpAddress=ip_address
        )
        
        if device.response:
            dev = device.response[0]
            print(f"\nāœ… Device found: {dev.hostname}")
            print(f"   Serial: {dev.serialNumber}")
            print(f"   Up Time: {dev.upTime}")
            return dev
        else:
            print(f"āŒ No device with IP: {ip_address}")
            return None
    except Exception as e:
        print(f"āŒ Error: {e}")
        return None

# Main execution
if __name__ == "__main__":
    # Get all devices
    all_devices = get_all_devices()
    
    # Filter by family
    get_devices_by_family("Switches and Hubs")
    
    # Filter by role
    get_devices_by_role("ACCESS")

3. ACI - Get Network Devices

ACI APIC API - List Fabric Nodes

#!/usr/bin/env python3
"""
ACI - Get Fabric Nodes (Devices)
Using APIC REST API
"""

import requests
import json

class ACIClient:
    def __init__(self, apic_url, username, password):
        self.base_url = apic_url
        self.username = username
        self.password = password
        self.token = None
        self.cookies = None
    
    def login(self):
        """Authenticate to APIC"""
        url = f"{self.base_url}/api/aaaLogin.json"
        
        payload = {
            "aaaUser": {
                "attributes": {
                    "name": self.username,
                    "pwd": self.password
                }
            }
        }
        
        response = requests.post(url, json=payload, verify=False)
        
        if response.status_code == 200:
            self.token = response.json()['imdata'][0]['aaaLogin']['attributes']['token']
            self.cookies = response.cookies
            print("āœ… ACI Authentication successful")
            return True
        else:
            print(f"āŒ Authentication failed: {response.status_code}")
            return False
    
    def get_fabric_nodes(self):
        """Get all fabric nodes (switches, controllers)"""
        url = f"{self.base_url}/api/node/class/fabricNode.json"
        
        response = requests.get(
            url,
            cookies=self.cookies,
            verify=False
        )
        
        if response.status_code == 200:
            nodes = response.json()['imdata']
            
            print("\n" + "="*70)
            print("ACI FABRIC NODES")
            print("="*70)
            print(f"\nāœ… Found {len(nodes)} node(s)\n")
            
            for node in nodes:
                attrs = node['fabricNode']['attributes']
                print(f"Name: {attrs.get('name', 'N/A')}")
                print(f"  ID: {attrs['id']}")
                print(f"  Role: {attrs.get('role', 'N/A')}")
                print(f"  Model: {attrs.get('model', 'N/A')}")
                print(f"  Serial: {attrs.get('serial', 'N/A')}")
                print(f"  Address: {attrs.get('address', 'N/A')}")
                print(f"  Status: {attrs.get('fabricSt', 'N/A')}")
                print("-" * 70)
            
            return nodes
        else:
            print(f"āŒ Error: {response.status_code}")
            return []
    
    def get_topology(self):
        """Get fabric topology"""
        url = f"{self.base_url}/api/node/class/topologySystem.json"
        
        response = requests.get(url, cookies=self.cookies, verify=False)
        
        if response.status_code == 200:
            print("\nāœ… Topology information retrieved")
            return response.json()['imdata']
        return []

# Usage
aci = ACIClient('https://apic.example.com', 'admin', 'password')
if aci.login():
    aci.get_fabric_nodes()

4. SD-WAN - Get Network Devices

SD-WAN vManage API - List Devices

#!/usr/bin/env python3
"""
SD-WAN - Get Network Devices
Using vManage REST API
"""

import requests
import json

class vManageAPI:
    def __init__(self, host, username, password):
        self.base_url = f"https://{host}"
        self.username = username
        self.password = password
        self.session = requests.Session()
        self.token = None
    
    def login(self):
        """Authenticate to vManage"""
        url = f"{self.base_url}/j_security_check"
        
        payload = {
            'j_username': self.username,
            'j_password': self.password
        }
        
        response = self.session.post(url, data=payload, verify=False)
        
        if response.status_code == 200:
            # Get XSRF token
            token_url = f"{self.base_url}/dataservice/client/token"
            token_response = self.session.get(token_url, verify=False)
            
            if token_response.status_code == 200:
                self.token = token_response.text
                self.session.headers.update({'X-XSRF-TOKEN': self.token})
                print("āœ… vManage authentication successful")
                return True
        
        print("āŒ Authentication failed")
        return False
    
    def get_devices(self):
        """Get all SD-WAN devices"""
        url = f"{self.base_url}/dataservice/device"
        
        response = self.session.get(url, verify=False)
        
        if response.status_code == 200:
            devices = response.json()['data']
            
            print("\n" + "="*70)
            print("SD-WAN DEVICES")
            print("="*70)
            print(f"\nāœ… Found {len(devices)} device(s)\n")
            
            for device in devices:
                print(f"Hostname: {device.get('host-name', 'N/A')}")
                print(f"  Device Type: {device.get('device-type', 'N/A')}")
                print(f"  Device Model: {device.get('device-model', 'N/A')}")
                print(f"  System IP: {device.get('system-ip', 'N/A')}")
                print(f"  Site ID: {device.get('site-id', 'N/A')}")
                print(f"  Version: {device.get('version', 'N/A')}")
                print(f"  Status: {device.get('status', 'N/A')}")
                print(f"  Reachability: {device.get('reachability', 'N/A')}")
                print("-" * 70)
            
            return devices
        else:
            print(f"āŒ Error: {response.status_code}")
            return []

# Usage
vmanage = vManageAPI('vmanage.example.com', 'admin', 'admin')
if vmanage.login():
    vmanage.get_devices()

5. NSO - Get Network Devices

NSO RESTCONF API - List Devices

#!/usr/bin/env python3
"""
NSO - Get Network Devices
Using RESTCONF API
"""

import requests
from requests.auth import HTTPBasicAuth
import json

class NSOClient:
    def __init__(self, host, username, password):
        self.base_url = f"http://{host}:8080/restconf/data"
        self.auth = HTTPBasicAuth(username, password)
        self.headers = {
            'Accept': 'application/yang-data+json',
            'Content-Type': 'application/yang-data+json'
        }
    
    def get_devices(self):
        """Get all devices managed by NSO"""
        url = f"{self.base_url}/tailf-ncs:devices/device"
        
        response = requests.get(
            url,
            auth=self.auth,
            headers=self.headers
        )
        
        if response.status_code == 200:
            devices = response.json()['tailf-ncs:device']
            
            print("="*70)
            print("NSO MANAGED DEVICES")
            print("="*70)
            print(f"\nāœ… Found {len(devices)} device(s)\n")
            
            for device in devices:
                print(f"Device: {device['name']}")
                print(f"  Address: {device.get('address', 'N/A')}")
                print(f"  Port: {device.get('port', 'N/A')}")
                print(f"  Device Type: {device.get('device-type', {}).get('cli', {}).get('ned-id', 'N/A')}")
                print(f"  State: {device.get('state', {}).get('admin-state', 'N/A')}")
                print("-" * 70)
            
            return devices
        else:
            print(f"āŒ Error: {response.status_code}")
            return []
    
    def check_device_sync(self, device_name):
        """Check if device is in sync"""
        url = f"{self.base_url}/tailf-ncs:devices/device={device_name}/check-sync"
        
        response = requests.post(
            url,
            auth=self.auth,
            headers=self.headers
        )
        
        if response.status_code == 200:
            result = response.json()
            in_sync = result.get('tailf-ncs:output', {}).get('in-sync', False)
            print(f"\n{'āœ…' if in_sync else 'āŒ'} Device {device_name} sync status: {in_sync}")
            return in_sync
        return None

# Usage
nso = NSOClient('nso.example.com', 'admin', 'admin')
nso.get_devices()

šŸ’¬ 3.9.b Manage Webex Spaces, Participants, and Messages

Overview

The Webex API provides comprehensive control over spaces (rooms), team memberships, and messaging.

Webex Teams API - Complete Management

šŸ“‹ Requirements:
  • Webex access token (from developer.webex.com)
  • Permissions: spark:all or specific scopes
#!/usr/bin/env python3
"""
Webex Teams - Complete Space and Message Management
Demonstrates spaces, participants, and messaging operations
"""

from webexteamssdk import WebexTeamsAPI
import os

# Initialize API
ACCESS_TOKEN = os.getenv('WEBEX_ACCESS_TOKEN', 'your_token_here')
api = WebexTeamsAPI(access_token=ACCESS_TOKEN)


# =============================================================================
# PART 1: SPACE MANAGEMENT
# =============================================================================

def list_spaces():
    """List all spaces (rooms)"""
    print("="*70)
    print("WEBEX SPACES")
    print("="*70)
    
    spaces = api.rooms.list()
    
    space_list = list(spaces)
    print(f"\nāœ… Found {len(space_list)} space(s)\n")
    
    for space in space_list:
        print(f"Title: {space.title}")
        print(f"  ID: {space.id}")
        print(f"  Type: {space.type}")
        print(f"  Created: {space.created}")
        print(f"  Last Activity: {space.lastActivity}")
        print("-" * 70)
    
    return space_list

def create_space(title, team_id=None):
    """Create a new space"""
    space = api.rooms.create(title=title, teamId=team_id)
    
    print(f"\nāœ… Space created:")
    print(f"   Title: {space.title}")
    print(f"   ID: {space.id}")
    print(f"   Type: {space.type}")
    
    return space

def get_space_details(space_id):
    """Get details of a specific space"""
    space = api.rooms.get(space_id)
    
    print(f"\nāœ… Space Details:")
    print(f"   Title: {space.title}")
    print(f"   Type: {space.type}")
    print(f"   Is Locked: {space.isLocked}")
    print(f"   Created: {space.created}")
    
    return space

def update_space(space_id, new_title):
    """Update space title"""
    space = api.rooms.update(roomId=space_id, title=new_title)
    print(f"āœ… Space updated to: {space.title}")
    return space

def delete_space(space_id):
    """Delete a space"""
    api.rooms.delete(space_id)
    print(f"āœ… Space {space_id} deleted")


# =============================================================================
# PART 2: PARTICIPANT (MEMBERSHIP) MANAGEMENT
# =============================================================================

def list_space_members(space_id):
    """List all members in a space"""
    print("\n" + "="*70)
    print(f"MEMBERS IN SPACE: {space_id}")
    print("="*70)
    
    memberships = api.memberships.list(roomId=space_id)
    
    member_list = list(memberships)
    print(f"\nāœ… Found {len(member_list)} member(s)\n")
    
    for member in member_list:
        print(f"Name: {member.personDisplayName}")
        print(f"  Email: {member.personEmail}")
        print(f"  ID: {member.personId}")
        print(f"  Is Moderator: {member.isModerator}")
        print(f"  Created: {member.created}")
        print("-" * 70)
    
    return member_list

def add_participant(space_id, person_email, is_moderator=False):
    """Add a person to a space"""
    membership = api.memberships.create(
        roomId=space_id,
        personEmail=person_email,
        isModerator=is_moderator
    )
    
    print(f"\nāœ… Added {person_email} to space")
    print(f"   Membership ID: {membership.id}")
    print(f"   Moderator: {membership.isModerator}")
    
    return membership

def update_participant(membership_id, is_moderator):
    """Update participant moderator status"""
    membership = api.memberships.update(
        membershipId=membership_id,
        isModerator=is_moderator
    )
    
    print(f"āœ… Updated membership - Moderator: {membership.isModerator}")
    return membership

def remove_participant(membership_id):
    """Remove a person from space"""
    api.memberships.delete(membership_id)
    print(f"āœ… Membership {membership_id} removed")


# =============================================================================
# PART 3: MESSAGE MANAGEMENT
# =============================================================================

def send_message(space_id, text):
    """Send a text message to a space"""
    message = api.messages.create(
        roomId=space_id,
        text=text
    )
    
    print(f"\nāœ… Message sent:")
    print(f"   ID: {message.id}")
    print(f"   Text: {message.text}")
    
    return message

def send_message_with_markdown(space_id, markdown_text):
    """Send message with Markdown formatting"""
    message = api.messages.create(
        roomId=space_id,
        markdown=markdown_text
    )
    
    print(f"āœ… Markdown message sent")
    return message

def send_message_with_file(space_id, text, file_urls):
    """Send message with file attachments"""
    message = api.messages.create(
        roomId=space_id,
        text=text,
        files=file_urls
    )
    
    print(f"āœ… Message with {len(file_urls)} file(s) sent")
    return message

def list_messages(space_id, max_messages=10):
    """List recent messages in a space"""
    print("\n" + "="*70)
    print(f"RECENT MESSAGES (Last {max_messages})")
    print("="*70)
    
    messages = api.messages.list(
        roomId=space_id,
        max=max_messages
    )
    
    for msg in messages:
        print(f"\nFrom: {msg.personEmail}")
        print(f"  Time: {msg.created}")
        print(f"  Text: {msg.text}")
        if hasattr(msg, 'files'):
            print(f"  Files: {len(msg.files)} attachment(s)")
    
    return list(messages)

def get_message_details(message_id):
    """Get specific message details"""
    message = api.messages.get(message_id)
    
    print(f"\nāœ… Message Details:")
    print(f"   From: {message.personEmail}")
    print(f"   Text: {message.text}")
    print(f"   Created: {message.created}")
    
    return message

def delete_message(message_id):
    """Delete a message"""
    api.messages.delete(message_id)
    print(f"āœ… Message {message_id} deleted")


# =============================================================================
# PART 4: COMPLETE WORKFLOW EXAMPLE
# =============================================================================

def webex_complete_workflow():
    """Complete workflow: Create space, add members, send messages"""
    
    print("\n" + "="*70)
    print("WEBEX COMPLETE WORKFLOW")
    print("="*70)
    
    # Step 1: Create a space
    print("\n1ļøāƒ£  Creating space...")
    space = create_space("DevOps Team - Automation")
    space_id = space.id
    
    # Step 2: Add participants
    print("\n2ļøāƒ£  Adding participants...")
    add_participant(space_id, "user1@example.com", is_moderator=False)
    add_participant(space_id, "user2@example.com", is_moderator=True)
    
    # Step 3: Send welcome message
    print("\n3ļøāƒ£  Sending welcome message...")
    send_message(space_id, "Welcome to the DevOps team space!")
    
    # Step 4: Send formatted message
    print("\n4ļøāƒ£  Sending formatted message...")
    markdown = """
    **Project Update**
    
    - āœ… API integration complete
    - 🚧 Testing in progress
    - šŸ“… Launch date: Next Monday
    """
    send_message_with_markdown(space_id, markdown)
    
    # Step 5: List all messages
    print("\n5ļøāƒ£  Listing messages...")
    list_messages(space_id, max_messages=5)
    
    # Step 6: List members
    print("\n6ļøāƒ£  Listing members...")
    list_space_members(space_id)
    
    print("\nāœ… Workflow completed successfully!")
    return space_id


# =============================================================================
# MAIN EXECUTION
# =============================================================================

if __name__ == "__main__":
    # List existing spaces
    spaces = list_spaces()
    
    # Run complete workflow (uncomment to execute)
    # webex_complete_workflow()

šŸ‘„ 3.9.c Obtain List of Clients/Hosts

Overview

Retrieving client/host information helps understand network usage, device connectivity, and user activity.

1. Meraki - Get Network Clients

Meraki Get Clients on Network

#!/usr/bin/env python3
"""
Meraki - Get Network Clients
Retrieve list of clients connected to network
"""

import meraki
from datetime import datetime, timedelta

API_KEY = "your_meraki_api_key"
dashboard = meraki.DashboardAPI(API_KEY, print_console=False)

def get_network_clients(network_id, timespan=86400):
    """
    Get clients seen on network
    
    Args:
        network_id: Network ID
        timespan: Time period in seconds (default: 86400 = 24 hours)
    """
    try:
        clients = dashboard.networks.getNetworkClients(
            networkId=network_id,
            timespan=timespan
        )
        
        print("="*70)
        print(f"NETWORK CLIENTS (Last {timespan/3600:.0f} hours)")
        print("="*70)
        print(f"\nāœ… Found {len(clients)} client(s)\n")
        
        for client in clients:
            print(f"Description: {client.get('description', 'Unnamed')}")
            print(f"  MAC: {client.get('mac', 'N/A')}")
            print(f"  IP: {client.get('ip', 'N/A')}")
            print(f"  Manufacturer: {client.get('manufacturer', 'Unknown')}")
            print(f"  OS: {client.get('os', 'Unknown')}")
            print(f"  VLAN: {client.get('vlan', 'N/A')}")
            print(f"  Status: {client.get('status', 'N/A')}")
            print(f"  Usage (sent): {client.get('usage', {}).get('sent', 0)} bytes")
            print(f"  Usage (recv): {client.get('usage', {}).get('recv', 0)} bytes")
            print(f"  Last Seen: {client.get('lastSeen', 'N/A')}")
            print("-" * 70)
        
        return clients
    except Exception as e:
        print(f"āŒ Error: {e}")
        return []

def get_client_details(network_id, client_id):
    """Get detailed information about specific client"""
    try:
        client = dashboard.networks.getNetworkClient(
            networkId=network_id,
            clientId=client_id
        )
        
        print(f"\nāœ… Client Details:")
        print(f"   MAC: {client.get('mac')}")
        print(f"   IP: {client.get('ip')}")
        print(f"   Description: {client.get('description', 'N/A')}")
        print(f"   User: {client.get('user', 'N/A')}")
        print(f"   Device Type: {client.get('deviceTypePrediction', 'Unknown')}")
        print(f"   Connection: {client.get('ssid', 'Wired')}")
        
        return client
    except Exception as e:
        print(f"āŒ Error: {e}")
        return None

def get_wireless_clients(network_id):
    """Get only wireless clients"""
    try:
        # Get all clients
        all_clients = dashboard.networks.getNetworkClients(
            networkId=network_id,
            timespan=3600
        )
        
        # Filter wireless (have SSID)
        wireless = [c for c in all_clients if 'ssid' in c]
        
        print(f"\nāœ… Wireless Clients: {len(wireless)}")
        for client in wireless:
            print(f"  - {client.get('description', client['mac'])}")
            print(f"    SSID: {client.get('ssid')}")
            print(f"    Signal: {client.get('rssi', 'N/A')} dBm")
        
        return wireless
    except Exception as e:
        print(f"āŒ Error: {e}")
        return []

def get_client_traffic_history(network_id, client_id):
    """Get traffic history for client"""
    try:
        # Get client policy
        policy = dashboard.networks.getNetworkClientPolicy(
            networkId=network_id,
            clientId=client_id
        )
        
        print(f"\nāœ… Client Policy:")
        print(f"   Device Policy: {policy.get('devicePolicy')}")
        print(f"   Group Policy: {policy.get('groupPolicyId', 'None')}")
        
        return policy
    except Exception as e:
        print(f"āŒ Error: {e}")
        return None

# Main execution
if __name__ == "__main__":
    NETWORK_ID = "L_1234567890"
    
    # Get all clients
    clients = get_network_clients(NETWORK_ID, timespan=3600)
    
    # Get wireless clients only
    get_wireless_clients(NETWORK_ID)
    
    # Get specific client details
    if clients:
        client_id = clients[0]['id']
        get_client_details(NETWORK_ID, client_id)

2. DNA Center - Get Clients/Hosts

DNA Center Client and Host Information

#!/usr/bin/env python3
"""
DNA Center - Get Client/Host Information
Using DNA Center SDK
"""

from dnacentersdk import DNACenterAPI

dnac = DNACenterAPI(
    username="admin",
    password="password",
    base_url="https://sandboxdnac.cisco.com",
    version='2.3.3.0',
    verify=False
)

def get_all_clients():
    """Get all clients/hosts on network"""
    try:
        clients = dnac.clients.get_client_detail()
        
        print("="*70)
        print("DNA CENTER - ALL CLIENTS")
        print("="*70)
        print(f"\nāœ… Found {len(clients.response)} client(s)\n")
        
        for client in clients.response[:10]:  # Show first 10
            print(f"Hostname: {client.get('hostName', 'Unknown')}")
            print(f"  User ID: {client.get('userId', 'N/A')}")
            print(f"  MAC: {client.get('hostMac', 'N/A')}")
            print(f"  IP: {client.get('hostIpV4', 'N/A')}")
            print(f"  Device Type: {client.get('hostType', 'N/A')}")
            print(f"  Connection: {client.get('connectionStatus', 'N/A')}")
            print(f"  VLAN: {client.get('vlanId', 'N/A')}")
            print(f"  Location: {client.get('location', 'N/A')}")
            print("-" * 70)
        
        return clients.response
    except Exception as e:
        print(f"āŒ Error: {e}")
        return []

def get_client_enrichment(mac_address):
    """Get enriched client information"""
    try:
        # Build entity value for MAC address
        enrichment = dnac.clients.get_client_enrichment_details(
            entity_type='mac_address',
            entity_value=mac_address
        )
        
        client_details = enrichment.response[0].get('clientDetails', {})
        
        print(f"\nāœ… Client Enrichment for {mac_address}:")
        print(f"   Hostname: {client_details.get('hostName', 'N/A')}")
        print(f"   Device Type: {client_details.get('deviceType', 'N/A')}")
        print(f"   Connected Device: {client_details.get('connectedDevice', [{}])[0].get('name', 'N/A')}")
        print(f"   Health Score: {client_details.get('healthScore', [{}])[0].get('score', 'N/A')}")
        print(f"   Issue Count: {client_details.get('issueCount', 0)}")
        
        return enrichment.response
    except Exception as e:
        print(f"āŒ Error: {e}")
        return None

def get_client_health():
    """Get overall client health"""
    try:
        health = dnac.clients.get_overall_client_health()
        
        print("\n" + "="*70)
        print("CLIENT HEALTH OVERVIEW")
        print("="*70)
        
        for score_cat in health.response:
            category = score_cat.get('scoreCategory', {})
            print(f"\nScore: {category.get('value', 'N/A')}")
            print(f"  Client Count: {category.get('clientCount', 0)}")
            print(f"  Client Unique: {category.get('clientUniqueCount', 0)}")
        
        return health.response
    except Exception as e:
        print(f"āŒ Error: {e}")
        return []

def search_clients_by_hostname(hostname):
    """Search for clients by hostname"""
    try:
        clients = dnac.clients.get_client_detail(hostName=hostname)
        
        print(f"\nāœ… Clients matching '{hostname}':")
        for client in clients.response:
            print(f"  - {client.get('hostName')} ({client.get('hostIpV4')})")
        
        return clients.response
    except Exception as e:
        print(f"āŒ Error: {e}")
        return []

# Main execution
if __name__ == "__main__":
    # Get all clients
    all_clients = get_all_clients()
    
    # Get client health
    get_client_health()
    
    # Get enrichment for specific client
    if all_clients:
        mac = all_clients[0].get('hostMac')
        if mac:
            get_client_enrichment(mac)

Quick Reference: Client Information APIs

Platform API Endpoint/Method Key Information Returned
Meraki getNetworkClients() MAC, IP, manufacturer, OS, VLAN, usage, last seen
DNA Center get_client_detail() Hostname, MAC, IP, device type, location, health score

šŸ Interactive Python Interpreter

šŸ’” How to use:
  • Write Python code in the editor below
  • Click "ā–¶ Run Code" to execute
  • Practice API operation patterns
šŸ“ Python Code Editor
⚔ Console Output
Ready to execute Python code...