cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
8473
Views
7
Helpful
18
Replies

using Python to get Device registration status

motolba
Cisco Employee
Cisco Employee

Hi All

     I am trying to write a simple code to get the device registration using Python

here is my code

result= client.service.SelectCmDevice('',{'SelectBy':'Name', 'Status':'Registered', 'Class':'Phone', 'SelectItems':{'SelectItem':{'Item':SEPXXXXXXXX}}})

everytime I run it I am receiving

MethodNotFound: Method not found: 'RISService70.RisPort70.SelectCmDevice'

now sure what is the problem

appreciate any guidance

18 Replies 18

dstaudt
Cisco Employee
Cisco Employee

Per the DevNet support Spark room it looks like you got this working, let us know if you have any further questions

hello,

I am facign exactly the same issue. Could you tell me how did you resolved it?

When I try tu run my Python code I got following:

Traceback (most recent call last):

  File "C:/Users/pdukat/Documents/GitHub/siptrunk/RisPort.py", line 33, in <module>

    result = client.service.SelectCmDevice('',{'SelectBy':'Name', 'Status':'Registered', 'Class':'Phone'})

  File "C:\Python34\lib\site-packages\suds\client.py", line 283, in __getattr__

    return getattr(port, name)

  File "C:\Python34\lib\site-packages\suds\client.py", line 387, in __getattr__

    return getattr(m, name)

  File "C:\Python34\lib\site-packages\suds\client.py", line 478, in __getattr__

    return self[name]

  File "C:\Python34\lib\site-packages\suds\client.py", line 491, in __getitem__

    raise MethodNotFound(qn)

suds.MethodNotFound: Method not found: 'RISService70.RisPort70.SelectCmDevice'

Here's a sample that works with my CUCM 10.5 system (Python 2.7.12):

# Installing a root/CA Certificate

# (Tested on Ubuntu 16.10)

# Retrieve certificate from CUCM

#    - openssl s_client -showcerts -connect cucm-node.example.com:443 </dev/null 2>/dev/null|openssl x509 >cucm-node.example.com.crt

# Store certificate on the client

#    - Create a directory for extra CA certificates in /usr/share/ca-certificates:

#        $ sudo mkdir /usr/share/ca-certificates/extra

#    - Copy the CA .crt file to this directory:

#        $ sudo cp foo.crt /usr/share/ca-certificates/extra/foo.crt

#    - Append the certificate path (relative to /usr/share/ca-certificates)

#        to /etc/ca-certificates.conf:

#        $ sudo dpkg-reconfigure ca-certificates

# In case of a .pem file, it must first be converted to a .crt file:

#    $ openssl x509 -in foo.pem -inform PEM -out foo.crt

# import logging

# logging.basicConfig(level=logging.INFO)

# logging.getLogger("suds.transport").setLevel(logging.DEBUG)

from suds.client import Client

url = 'file:///home/dstaudt/Documents/Serviceability/v10.5(1)/RISService70.wsdl'

client = Client(url,

                location='https://ds-ucm105.cisco.com:8443/realtimeservice2/services/RISService70/',

                username='Administrator',

                password='ciscopsdt')

stateInfo = None

criteria = client.factory.create('CmSelectionCriteria')

item = client.factory.create('SelectItem')

mod = client.factory.create('CmSelectionCriteria.Model')

criteria.MaxReturnedDevices = 500

criteria.DeviceClass = 'Phone'

criteria.Model = 255

criteria.Status = 'Any'

criteria.NodeName = ''

criteria.SelectBy = 'Name'

item.Item = 'IPCMRAEU5UCM5X7'

criteria.SelectItems.item.append(item)

criteria.Protocol = 'Any'

criteria.DownloadStatus = 'Any'

result = client.service.selectCmDevice(stateInfo, criteria)

print result

Thank You!

With some minor changes it started working for me!

Thanks for the code example dstaudt!  I can verify the suds-jurko client connection is successful with CUCM11.5.

Python 2.7.12

suds-jurko 0.6

I was having trouble parsing the SOAP/suds selectCmDevice response with Python.  Some of the examples in the support forums and other blogs/sites were referencing the below for loop:

for node in result['SelectCmDeviceResult']['CmNodes']:

    for device in node['CmDevices']:

        print device['Name'], device['DirNumber'], device['Description']

This would result in an error for me with:

Traceback (most recent call last):

  File "<stdin>", line 2, in <module>

TypeError: tuple indices must be integers, not str

I might be missing something simple not coming from a programming background but I thought I'd provide the solution I came up with to parse the SOAP response in case anyone else is struggling.

for node in result['SelectCmDeviceResult']['CmNodes']['item']:

    if node['CmDevices'] != None:

        for device in node['CmDevices']['item']:

             print device['Name'], device['DirNumber'], device['Description']

Suds also supports the dot notation to specify nested types so the below works as well:

for node in result.SelectCmDeviceResult.CmNodes.item:

    if node.CmDevices != None:

        for device in node.CmDevices.item:

             print device.Name, device.DirNumber, device.Description

You're treating the tuple like a dict and trying to call a key, when the type is a tuple (i.e. ummutable list) and you need to specify a numeric index.

Review the traceback error and determine where you're doing this, then pass the necessary tuple index to extract the data that you want.  It may help to do some debugging and testing with print(type(your_object)) to see what is expected at each point.

Thanks for the info Jonathan, yeah I was seeing that as well in troubleshooting how to parse the response.  I guess it depends on your search criteria as well, I was querying for phones in a registered status across all nodes.  A tuple is returned but depending on your CUCM CMGroup design there might not always be an expected CmNodes index that a phone is registered to.  So defining an explicit index (item[0] [1]) worked, but just wasn't giving me the data I was looking for.

>>> print type(result.SelectCmDeviceResult)

<class 'suds.sudsobject.SelectCmDeviceResult'>

>>> print type(result.SelectCmDeviceResult.CmNodes)

<class 'suds.sudsobject.ArrayOfCmNode'>

>>> print type(result.SelectCmDeviceResult.CmNodes.item)

<type 'list'>

>>> for node in result.SelectCmDeviceResult.CmNodes:

...     print type(node)

...

<type 'tuple'>

>>> print result

(selectCmDeviceReturn){

   SelectCmDeviceResult =

      (SelectCmDeviceResult){

         TotalDevicesFound = 1

         CmNodes =

            (ArrayOfCmNode){

               item[] =

                  (CmNode){

                     ReturnCode = "NotFound"

                     Name = "ccm-pub01"

                     NoChange = True

                     CmDevices = None

                  },

                  (CmNode){

                     ReturnCode = "NotFound"

                     Name = "ccm-sub01"

                     NoChange = False

                     CmDevices = None

                  },

                  (CmNode){

                     ReturnCode = "NotFound"

                     Name = "ccm-sub02"

                     NoChange = False

                     CmDevices = None

                  },

                  (CmNode){

                     ReturnCode = "Ok"

                     Name = "ccm-sub03"

                     NoChange = False

                     CmDevices =

                        (ArrayOfCmDevice){

                           item[] =

                              (CmDevice){

                                 Name = "SEPXXXXXXXXXXXX"

                                 DirNumber = "XXXXXXXXXX-Registered"

                                 DeviceClass = "Phone"

                                 Model = 111

                                 Product = 111

                                 BoxProduct = 0

                                 Httpd = "Yes"

                                 RegistrationAttempts = 0

                                 IsCtiControllable = True

                                 LoginUserId = "XXXXXXXXXX"

                                 Status = "Registered"

                                 StatusReason = 0

                                 PerfMonObject = 2

                                 DChannel = 0

                                 Description = "Phone Description"

                                 H323Trunk =

                                    (H323Trunk){

                                       ConfigName = None

                                       TechPrefix = None

                                       Zone = None

                                       RemoteCmServer1 = None

                                       RemoteCmServer2 = None

                                       RemoteCmServer3 = None

                                       AltGkList = None

                                       ActiveGk = None

                                       CallSignalAddr = None

                                       RasAddr = None

                                    }

                                 TimeStamp = 1111111111

                                 Protocol = "SIP"

                                 NumOfLines = 1

                                 LinesStatus =

                                    (ArrayOfCmDevSingleLineStatus){

                                       item[] =

                                          (CmDevSingleLineStatus){

                                             DirectoryNumber = "XXXXXXXXXX"

                                             Status = "Registered"

                                          },

                                    }

                                 ActiveLoadID = "firmware"

                                 InactiveLoadID = "firmware"

                                 DownloadStatus = "Unknown"

                                 DownloadFailureReason = None

                                 DownloadServer = None

                                 IPAddress =

                                    (ArrayOfIPAddressArrayType){

                                       item[] =

                                          (IPAddressArrayType){

                                             IP = "x.x.x.x"

                                             IPAddrType = "ipv4"

                                             Attribute = "Unknown"

                                          },

                                    }

                              },

                        }

                  },

                  (CmNode){

                     ReturnCode = "NotFound"

                     Name = "ccm-sub04"

                     NoChange = False

                     CmDevices = None

                  },

                  (CmNode){

                     ReturnCode = "NotFound"

                     Name = "ccm-sub05"

                     NoChange = False

                     CmDevices = None

                  },

                  (CmNode){

                     ReturnCode = "NotFound"

                     Name = "ccm-sub06"

                     NoChange = False

                     CmDevices = None

                  },

                  (CmNode){

                     ReturnCode = "NotFound"

                     Name = "ccm-sub07"

                     NoChange = False

                     CmDevices = None

                  },

            }

      }

   StateInfo = "...some state info omitted"

}

This is coming from a non-programming background so that was just the method I came up with (mostly trial and error with the Python interpreter, and lots of forum crawling).  If there is a more efficient or elegant solution I'm definitely in!

I'd suggest use a decent IDE and run this through the debugger.  You can look at the types of the nested object more easy way.  It's easier than using print statements.

As an aside, I really suggest moving to use zeep instead of suds.  It's actively developed and maintained and has some very useful helper functions.

I will try give you a decent sample for this API using zeep when I can.  I'm busy developing a Python wrapper for AXL, and I do want to support the API as well in any case.

I am also facing same issue,
Added few commands as below, but getting error. Would you pls. share with me, if you find any better way in displaying output ?
result = client.service.selectCmDevice(stateInfo, criteria)
for node in (result['SelectCmDeviceResult']['CmNodes']):
for device in node['CmDevices']:
print (device['Name'], device['IpAddress'], device['DirNumber'], device['Description'])

If I just print (result) I am getting output as below output, I want to display output in proper way, onlt name, IP address, directory number and description
But while adding "for device in node" I am getting error on this line as below;
for device in node['CmDevices']:
error is:
Traceback (most recent call last):
File "phone2.py", line 40, in <module>
for device in node['CmDevices']:
TypeError: string indices must be integers

Pls. advice why TypeError: string indices must be integers

I am trying to write Python script to display only registered IP Phones detail from Cisco CUCM ver. 11.5

I’m getting one error while displaying output as mentioned below.

 

from zeep import Client

from zeep.cache import SqliteCache

from zeep.transports import Transport

from zeep.plugins import HistoryPlugin

from requests import Session

from requests.auth import HTTPBasicAuth

from lxml import etree

import urllib3

from urllib3 import disable_warnings

from urllib3.exceptions import InsecureRequestWarning

username = 'xxxx'

password = 'xxxx'

wsdl = 'https://x.x.x.x:8443/realtimeservice2/services/RISService70?wsdl'

session = Session()

session.verify = False

session.auth = HTTPBasicAuth(username, password)

transport = Transport(cache=SqliteCache(), session=session, timeout=20)

history = HistoryPlugin()

client = Client(wsdl=wsdl, transport=transport, plugins=[history])

factory = client.type_factory('ns0')

macs = ['*'] #'*' for all

item=[]

for mac in macs:

    item.append(factory.SelectItem(Item=mac))

    Item = factory.ArrayOfSelectItem(item)

stateInfo = ''

criteria = factory.CmSelectionCriteria(

    MaxReturnedDevices = 1000,

    DeviceClass='Phone',

    Model=255,    #255 for all

    Status='Registered',

    NodeName='',

    SelectBy='Name',

    SelectItems=Item,

    Protocol='Any',

    DownloadStatus='Any'

)

result = client.service.selectCmDevice(stateInfo, criteria)

for node in (result['SelectCmDeviceResult']['CmNodes']):

    for device in node['CmDevices']:

        print (device['Name'], device['IpAddress'], device['DirNumber'], device['Description'])

 

 

 

If I just print (result) I am getting output as below output, I want to display output in proper way. Only name, IP address, directory number and description

But while adding "for device in node" I am getting error on this line as below;

for device in node['CmDevices']:

error is:

Traceback (most recent call last):

  File "phone2.py", line 40, in <module>

    for device in node['CmDevices']:

TypeError: string indices must be integers

 

Pls. advice why TypeError: string indices must be integers

 

Script Output from Cisco CallManager, while running the script with only print (result)

{

    'SelectCmDeviceResult': {

        'TotalDevicesFound': 43,

        'CmNodes': {

            'item': [

                {

                    'ReturnCode': 'NotFound',

                    'Name': '10.10.161.10',

                    'NoChange': False,

                    'CmDevices': {

                        'item': []

                    }

                },

                {

                    'ReturnCode': 'Ok',

                    'Name': '10.10.161.11',

                    'NoChange': False,

                    'CmDevices': {

                        'item': [

                            {

                                'Name': 'SEP009AD2D3E9C0',

                                'DirNumber': '7010-Registered',

                                'DeviceClass': 'Phone',

                                'Model': 688,

                                'Product': 573,

                                'BoxProduct': 0,

                                'Httpd': 'Yes',

                                'RegistrationAttempts': 1,

                                'IsCtiControllable': True,

                                'LoginUserId': None,

                                'Status': 'Registered',

                                'StatusReason': 0,

                                'PerfMonObject': 2,

                                'DChannel': 0,

                                'Description': 'SEP009AD2D3E9C0',

                                'H323Trunk': {

                                    'ConfigName': None,

                                    'TechPrefix': None,

                                    'Zone': None,

                                    'RemoteCmServer1': None,

                                    'RemoteCmServer2': None,

                                    'RemoteCmServer3': None,

                                    'AltGkList': None,

                                    'ActiveGk': None,

                                    'CallSignalAddr': None,

                                    'RasAddr': None

                                },

                                'TimeStamp': 1561098640,

                                'Protocol': 'SIP',

                                'NumOfLines': 1,

                                'LinesStatus': {

                                    'item': [

                                        {

                                            'DirectoryNumber': '7010',

                                            'Status': 'Registered'

                                        }

                                    ]

                                },

                                'ActiveLoadID': 'ce-9.3.0-d31e4c18-2017-11-21',

                                'InactiveLoadID': None,

                                'DownloadStatus': 'Unknown',

                                'DownloadFailureReason': None,

                                'DownloadServer': None,

                                'IPAddress': {

                                    'item': [

                                        {

                                            'IP': '10.10.161.187',

                                            'IPAddrType': 'ipv4',

                                            'Attribute': 'Unknown'

                                        }

                                    ]

                                }

                            },

                            {

                                'Name': 'SEP00A3D15CBB31',

                                'DirNumber': '7020-Registered',

                                'DeviceClass': 'Phone',

                                'Model': 690,

                                'Product': 575,

                                'BoxProduct': 0,

                                'Httpd': 'Yes',

                                'RegistrationAttempts': 1,

                                'IsCtiControllable': True,

                                'LoginUserId': None,

                                'Status': 'Registered',

                                'StatusReason': 0,

                                'PerfMonObject': 2,

                                'DChannel': 0,

                                'Description': 'Africa MR',

                                'H323Trunk': {

                                    'ConfigName': None,

                                    'TechPrefix': None,

                                    'Zone': None,

                                    'RemoteCmServer1': None,

                                    'RemoteCmServer2': None,

                                    'RemoteCmServer3': None,

                                    'AltGkList': None,

                                    'ActiveGk': None,

                                    'CallSignalAddr': None,

                                    'RasAddr': None

                                },

It looks like under <CmDevices> is an <items> list, which you have to index with a number:

    for device in node['CmDevices']['item']:

        ipaddresses = device['IPAddress']

        ipaddress = ipaddresses['item'][0]['IP'] if ipaddresses else ''

I created a sample that shows how to create a simple console report:

https://github.com/CiscoDevNet/serviceability-python-zeep-samples/

Thanks a lot. This feedback resolved the issue. Your feedback was very useful.

Appreciate, if you can provide me link, how to understand the output which I shared before. I still could not get the concept of SelectCmDeviceResult']['CmNodes']['item']):

 

Issue rectified with below correction.

for node in (result['SelectCmDeviceResult']['CmNodes']['item']):
for device in node['CmDevices']['item']:
ipaddresses = device['IPAddress']
ipaddress = ipaddresses['item'][0]['IP'] if ipaddresses else ''
print (device['Name'], ipaddress, device['DirNumber'], device['Model'], device['Protocol'], device['Description'])

Hi

Issue fixed with your help. But same script doesn't work on CUCM ver 12.5, it works perfectly on CUCM ver 11.5.

Do you have any clues ?

 

Rgds

Rajesh

Hi
for CUCM version 12.5
inside https://<cucmIP>:8443/realtimeservice2/services/RISService70?wsdl
I have below entry.
<wsdlsoap:address location="https://localhost:8443/realtimeservice2/services/RISService70"/>

but for CUCM 11.5
locahost is replaced with specific IP address. Is that could be causing the issue ?