cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1532
Views
0
Helpful
1
Replies

Serviceability API - getting more than 1000 results?

Randall White
Level 3
Level 3

By default, the CUCM Serviceability API returns a maximum of 1000 devices.

How can I get more than that?

I am modifying Alexey Smirnov's Python script found here: https://communities.cisco.com/docs/DOC-59446

There is a single statement "response=requests.post('https://' + CMserver + ':8443/......" that returns 1000 results (as expected).

I know the AXL API has a SKIP/FIRST feature in the requests that allows you to get the next group of results, but I can't find anything similar in Serviceability. I have played around with MaxReturnedDevices, but that only limits the  number to less than 1000.

Here is my code, it works great in Python 3.6 with CUCM 10.5.2. It spits the results into a CSV file, the problem is I have around 7000 phones, and the script quits at 1000. Please note that I am a beginner at scripting in Python.

thanks, Randy

.....................................................

#works in Python 3.6

import requests 

import csv

import xml.etree.ElementTree 

from requests.auth import HTTPBasicAuth 

import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

#Ask user some questions

fileName = input('Enter the CSV filename: ')

CMserver= input('Enter Publisher IP: ') 

serv_user= input('Enter AXL Username: ') 

serv_pass= input('Enter AXL User Password: ')

 

model='255'      #255 returns all phone models

#create and open your CSV file

outputFile = open(fileName + '.csv', 'w', newline='')

outputWriter = csv.writer(outputFile)

outputWriter.writerow(["Host Name", "DN", "IP Address", "Status"]) #create the header row

raw_xml = """<?xml version="1.0" encoding="UTF-8"?>

            <SOAP-ENV:Envelope

            xmlns:ns3="http://www.w3.org/2001/XMLSchema"

            xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"

            xmlns:ns0="http://schemas.xmlsoap.org/soap/encoding/"

            xmlns:ns1="http://schemas.cisco.com/ast/soap/"

            xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/"

            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

            xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

            SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

            <SOAP-ENV:Header/>

                <ns2:Body>

                <ns1:SelectCmDevice>

                    <StateInfo xsi:type="ns3:string"></StateInfo>

                    <CmSelectionCriteria xsi:type="ns1:CmSelectionCriteria">

                        <ns1:Class xsi:type="ns3:string">Phone</ns1:Class>

                        <ns1:Model xsi:type="ns3:unsignedInt">{0}</ns1:Model>

                        <ns1:SelectBy xsi:type="ns3:string">Name</ns1:SelectBy>

                    </CmSelectionCriteria>

                </ns1:SelectCmDevice>

                </ns2:Body>

            </SOAP-ENV:Envelope>""".format(model) 

headers={'SOAPAction': '"http://schemas.cisco.com/ast/soap/action/#RisPort#SelectCmDevice"',  

         'Content-Type': 'text/xml; charset=utf-8',  

         'Content-type': 'text/xml; charset=utf-8',  

         'Soapaction': '"http://schemas.cisco.com/ast/soap/action/#RisPort#SelectCmDevice"'} 

response=requests.post('https://' + CMserver + ':8443/realtimeservice/services/RisPort',data=raw_xml,headers=headers, auth=HTTPBasicAuth(serv_user, serv_pass),verify=False) 

tree = xml.etree.ElementTree.fromstring(response.text) 

CmNodes = tree.find("{http://schemas.xmlsoap.org/soap/envelope/}Body").find("{http://schemas.cisco.com/ast/soap/}SelectCmDeviceResponse").find("SelectCmDeviceResult").find("CmNodes") 

for node in CmNodes: 

    for devs in node.find("CmDevices"): 

#    Now write the data to a row in yor CSV

        outputWriter.writerow([devs.find('Name').text, devs.find('DirNumber').text, devs.find('IpAddress').text, devs.find('Status').text])

#    When you have iterated through all rows, close the file

outputFile.close()     

print("All Done")

1 Reply 1

My advice with this would be to approach your task a bit differently and instead explicitly request every individual phone.

 

You could for instance with AXL perform a listPhone with a searchCriteria of '%' to get every single device on the cluster. Then you can save the <name> into a list.

 

Once you have this, you can build a SOAP Query to RisPort70 API, specifically requesting each name, up to 1000, then get the results. Then perform the next 1000, and so on.


Here's a simple example to split up a list into desired chunks, where phone_list is a list that contains ALL phones:

 

As a List Comprehension:

split_phone_list = [phone_list[x:x+1000] for x in range (0, len(phone_list), 1000)]

This will give you a single list that contains sub-lists containing no more than 1000 items.

 

Then you can loop through the outer list, and for each iteration make a single RisPort70 query using the names from the inner list.

 

Hope this helps.... I can tell you it will be a lot easier for you if you use a SOAP library like python-zeep so that you don't have to deal with the raw SOAP envelope. I did a blog post on this a while back with the Serviceability API: https://paultursan.com/2018/12/getting-cucm-real-time-data-via-risport70-with-python-and-zeep-cisco-serviceability-api/

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: