01-11-2017 03:04 PM
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
01-11-2017 03:13 PM
Per the DevNet support Spark room it looks like you got this working, let us know if you have any further questions
04-04-2017 12:29 AM
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'
04-04-2017 02:00 PM
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
04-04-2017 11:50 PM
Thank You!
With some minor changes it started working for me!
04-05-2018 09:10 AM
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
04-06-2018 12:55 AM
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.
04-06-2018 06:54 AM
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!
04-09-2018 05:42 AM
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.
06-21-2019 02:08 AM
06-21-2019 02:10 AM
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
},
06-21-2019 12:16 PM
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/
06-21-2019 03:15 PM
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'])
06-22-2019 09:53 AM
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
06-23-2019 03:14 AM
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide