Querying CUCM via AXL – sample Python script

* Update: I re-formated the code below at ~4pm EDT on 2/28/2018 so if you copied and pasted the code prior to that time, you may have encountered errors. Python is very picky about spaces and indentations so I’ve corrected the spacing in the code below.

Here’s a sample script which is used to query CUCM via AXL for a list of phone devices.

The script discovers the file path to the script, prompts for a client name, creates a new directory based on the client name entered, prompts for CUCM info (IP address, version (to load the correct AXL schema file), username and password. Once authenticated, the script queries CUCM for a list of phone devices and creates a .csv containing the query results in the newly created client directory. There’s not much validation or exception handling in this sample script, but if you’d like to see what I normally do for exception handling, hit me up on Twitter @IPTInfo.

This script was tested on both Windows 7 and on MacOS High Sierra using Python 3.6.4 on both platforms. The prerequisites for this script are:

  • Python3
  • zeep
  • suds-jurko
  • CUCM user with AXL access
  • AXL Toolkit download and extracted to the same directory as this script.

import ssl
import os
import datetime
import getpass
import urllib
import urllib.error
import sys
import time
from suds.client import WebFault
from suds.xsd.doctor import Import
from suds.xsd.doctor import ImportDoctor
from suds.client import Client

# Ignore certificates
ssl._create_default_https_context = ssl._create_unverified_context

# prompt for client name and CUCM version.
clientname = input('Input client name: ')
ccmversion = input('CUCM version: ')

# discover current path
ospath = os.getcwd()

#  replace backslashes in windows file path with forward slashes
ospath = (ospath.replace('\\', '/'))

# create directory with same name as client entered previously
clientpath = ospath + '/' + clientname + '/'
isDirectory = os.path.isdir(clientpath)

# check to see if directory already exists, if not, create the directory
if (isDirectory):
  print("Client directory already exists at " + clientpath )
  print("Creating client directory at " + clientpath )
  os.mkdir(clientpath, mode=0o777)

# get timestamp and create csv file with concatenated name of client and timestamp in path above
dt = datetime.datetime.now()
dt = dt.replace(microsecond=0)
strdt = str(dt)
strdt = (strdt.replace(':', '').replace('-','').replace(' ','').replace('.',''))
file_path = clientpath + '_phone_devices_' + strdt + '.csv'
status = open(file_path,'w')

    tns = 'http://schemas.cisco.com/ast/soap/'
    imp = Import('http://schemas.xmlsoap.org/soap/encoding/', 'http://schemas.xmlsoap.org/soap/encoding/')

    # prompt for CUCM IP address, username and password. 

    cmserver = input('Input CUCM IP Address: ')
    cmport = '8443'
    ospath = (ospath.replace('\\','/'))
    wsdl = 'file:///' + ospath + '/axlsqltoolkit/schema/' + ccmversion + '/AXLAPI.wsdl'
    print('Searching for AXL schema files in: ' + wsdl)
    location = 'https://' + cmserver + ':8443/axl/'
    AXL_USER = input('Input AXL username: ')
    AXL_PASS = getpass.getpass('Input CUCM AXL password: ')

    # connect to CUCM and query for phone devices
    client = Client(wsdl,location=location, username=AXL_USER, password=AXL_PASS, plugins=[ImportDoctor(imp)])
    result = client.service.listPhone({'name':'SEP%'},{'name':'','description':'','model':'','protocol':''})
    status.write("Device Name" + "," + "Descripton" + "," + "Phone Model" + "," + "Protocol "+'\n')
    if result['return'] == "":
      print("No Phone devices configured.")
      status.write("No Phone devices configured." + '\n')
      for node in result['return']['phone']:
        status.write(str(node['name']) + "," + str(node['description']) + "," + str(node['model']) + "," + str(node['protocol']) + '\n')
        print (str(node['name']), str(node['description']), str(node['model']),str(node['protocol']))
except Exception as e:
    #write data to CSV file and close the file
print('Query completed.')


  • zip listphones.py
    Python script file discussed above
    File size: 2 KB Downloads: 277