11-28-2014 07:19 AM
Hello,
I have a nice working toolset that is interacting very well with AXL interface using PHP.
However, we are looking to switch to python (it does look like this would be a lot easier to process data coming in). Unfortunately, i can't find any working example to connect to the AXL interface.
suds seems to be the way to go, but that's not working on python3. I'm happy doing this in python2, but still, i don't get suds to get the works done ... any working example is welcome! (i'll give you a working PHP example in return ;p )
Jan.
12-01-2014 07:34 AM
Jan,
Below I have provided some sample code to use with AXL. I use the "Requests" libraries to process HTTP so if you use the below code exactly you will need to download the Requests library for python. Also, and I am sure you know this, but please change your keep your AXL version consistent with the CUCM you are using. The below code is using AXL 8.5. Let me know if you have any questions.
Thank You,
Jock
import requests
import xml.etree.ElementTree as ET
soaprequest = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.cisco.com/AXL/API/8.5"><soapenv:Header /><soapenv:Body><ns:listPhone><searchCriteria><name>SEP%</name></searchCriteria><returnedTags><name></name></returnedTags></ns:listPhone></soapenv:Body></soapenv:Envelope>'
soapheaders = {'Content-type':'text/xml', 'SOAPAction':'CUCM:DB ver=8.5 listPhone'}
AXLRequest = requests.post('https://CMServer:8443/axl/', data = soaprequest, headers = soapheaders, verify = False, auth=('username','password'))
root = ET.fromstring(AXLRequest.text)
DeviceNames = []
for phone in root.iter('phone'):
DeviceNames.append(phone.find('name').text)
#print phone.find('name').text
print DeviceNames
12-01-2014 08:43 AM
Thx Kristopher, that's indeed working and a good first step ;-)
Kind of complicated, though. I do use quite a few methods and with the php SoapClient, i can just load the connection with the xdml file and give the parameters in a nice array / list ... and get the stuff back in sort of a nice way.
So if anyone can give a working example using SUDS, that would be perfect.
I did find something that's working in Python2 for the RIS interface:
Parky's Place: Using Python to call Cisco Communications Manager Serviceability SOAP API
Havent' been able to port that to work with AXL though ...
12-01-2014 12:43 PM
For what it's worth, I've tried AXL with Python Suds and pysimplesoap. Suds seems to create XML that AXL doesn't like, and I get this error when I try to use an API:
AttributeError: 'NoneType' object has no attribute 'promotePrefixes'
I get a little farther with Pysimplesoap, but in the end I haven't figured out how to call an API. Here's code to get you started, though, if you're interested (substitute your own username, password, and server, and point to the place where you have the WSDL and XSDs):
from pysimplesoap.client import SoapClient
import base64
wsdl="http://localhost/AXLAPI.wsdl"
location="https://server:8443/axl"
action="https://server:8443/axl"
ns='http://schemas.cisco.com/ast/soap/'
username="username"
password="password"
toencode=username + ':' + password
encoded=base64.b64encode(bytes(toencode,"utf-8"))
client = SoapClient(wsdl=wsdl, location=location, action=action, ns=ns, http_headers={'Authorization': 'Basic %s' % encoded})
print(client.help('listPhone'))
12-01-2014 03:07 PM
try this Python SUDS code. I am running this on Python 2.7.8 on Windows 7
from suds.client import Client
cmserver = '10.10.10.10'
cmport = '8443'
wsdl = 'file:///your/system/path/schema/current/AXLAPI.wsdl'
location = 'https://' + cmserver + ':' + cmport + '/axl/'
username = 'username'
password = 'password'
client = Client(wsdl,location=location, username=username, password=password)
result = client.service.listPhone({'name':'SEP%'},{'name':'','model':''})
for node in result['return']['phone']:
print str(node['name']), str(node['model'])
08-03-2016 11:14 PM
I am getting below error when i am running given code:
result = client.service.listPhone({'name':'SEPEXXXXD958F06'},{'name':'','model':''})
print(result)
for node in result['return']['phone']:
print str(node['name']), str(node['model'])
************
(200, (reply){
return =
(return){
phone[] =
(LPhone){
_uuid = "{51D5AC0A-E3F9-C05B-B446-4F1ACD6D0472}"
name = "SEPEXXXXD958F06"
model = "Cisco 7945"
},
}
})
Traceback (most recent call last):
File "C:\Python27\Scripts\Listphone1.py", line 58, in <module>
for node in result['return']['phone']:
TypeError: tuple indices must be integers, not str
Any help will be appreciated.
12-03-2014 03:04 PM
Waw, i think i have figured it out ... but it's a bit a painful one. Got it working for get* methods too now, list is working also (as it always did), still have to try add* stuff.
So, here's how it goes:
As I don't know suds at all, here's a very rudimentary example for a get* request (pretty much based on the answers above ;p)
wsdl = 'file:///C:/path/to/your/matching/AXLAPI.wsdl'
from suds.client import Client
client = Client(wsdl,location='https://yourserverhere:8443/axl/',username='yourusername',password='yourpassword')
phone = client.service.getPhone(name='test')
print(phone)
(reply){
return =
(return){
phone =
(RPhone){
_uuid = "{50BCA715-C781-C8B0-CC90-E0B95CB2F1AD}"
_ctiid = 9
name = "jseynaev-test"
description = "jseynaev-test"
product = "Cisco IP Communicator"
< ... very long list of params ... >
Let me know if this works for you too!
Jan.
12-03-2014 03:28 PM
I did a pip install suds-jurko with Python34, and it didn't install C:\Python34\Lib\site-packages\suds\bindings\document.py. I believe everything necessary is packed in the egg file, and I didn't extract it or edit document.py there.
However, the following code still worked fine for me:
from suds.client import Client
from suds.transport.https import HttpAuthenticated
cmserver = 'server'
cmport = '8443'
wsdl = 'PATH/TO/AXLAPI.wsdl'
location = 'https://' + cmserver + ':' + cmport + '/axl/'
username = 'username'
password = 'password'
client = Client(wsdl,location=location, transport = HttpAuthenticated(username=username, password=password))
result = client.service.listPhone({'name':'SEP%'},{'name':'','model':''})
for node in result['return']['phone']:
print (str(node['name']), str(node['model']))
12-04-2014 12:41 AM
Yes, the list* calls seem to work fine 'out of the box', however, things like getPhone or getRegion (try e.g. region = client.service.getRegion(name='Default')) throw an error of some non-defined property ...
Not sure how the whole pip install works, but for me that's where the file was, maybe it installed it somewhere in your home directory? (i choose to install 'for everyone on this pc')
12-04-2014 08:15 AM
This works for me in the above example in place of listPhone:
result = client.service.getPhone(name='SEP010101010101')
print(result)
I tried various ways of specifying returnedTags, but nothing I tried worked. Suds is not extremely well documented when it comes to using a WSDL like AXLAPI. By the way, I'm using the 10.5 WSDL against a 10.5 CUCM.
12-04-2014 08:37 AM
I agree with Nick. There is not a lot of documentation for using AXL with suds or any other python soap handlerfor that matter, even pysimplesoap. His assessment is also correct with usage of tags. Trying to find out exactly what works with suds was a little difficult. when I posted my code in my last post the only way I was able to figure it out for the listPhone was through a little trial and error with the tags. Also, I was able to get it to work without patching the file you mentioned
I think depending on the call you are using you might have to adjust how you write the tags, so you might have a little trial and error on that one. which would be a benefit in the future maintaining your code. That being said you could always use the old fashioned way like my very first post on this thread, depends on your preference and how simple or complex you want to make it considering your trade offs of time and how mush maintenance you are willing to do to your code.
Below is the final code sample I have combining Nick's testing and my own. Let us know if that works for you or if you are having trouble with any other calls in AXL.
from suds.client import Client
cmserver = '10.10.10.10'
cmport = '8443'
wsdl = 'file:///your/file/location/schema/current/AXLAPI.wsdl'
location = 'https://' + cmserver + ':' + cmport + '/axl/'
username = 'user'
password = 'pass'
client = Client(wsdl,location=location, username=username, password=password)
result = client.service.getPhone(name = 'IPCMRAEU5UCM5X7')
print result
12-04-2014 09:07 AM
I forgot to mention that in my last post the code is utilizing the 9.1 version of AXL.
08-06-2017 03:51 AM
Hi Jan & everyone,
I know I am a very late entrant to this but I am stuck at the same point which is being discussed in this forum. I've tried multiple combinations of the script but the error keeps popping up. Following is one of the script examples that I tried after importing URLLIB2 since URLLIB doesn't work with Python 2.7 . Any kind of help or direction will be greatly appreciated. I've hit a dead end on my own.
***************************************************
import ssl
import urllib
import urllib2
from suds.client import Client
from suds.transport.https import HttpAuthenticated
from suds.xsd.doctor import Import
import logging
from suds.xsd.doctor import ImportDoctor
t = HttpAuthenticated(username='ccmadmin', password='pswd')
t.handler = urllib2.HTTPBasicAuthHandler(t.pm)
ssl_def_context = ssl.create_default_context()
ssl_def_context.check_hostname = False
ssl_def_context.verify_mode = ssl.CERT_NONE
t1=urllib2.HTTPSHandler(ssl_def_context)
t.urlopener = urllib2.build_opener(t.handler,t1)
wsdl = 'file:///C:/actual path/axlsqltoolkit/schema/current/AXLAPI.wsdl'
location = 'https://10.1.2.5:8443/axl/'
username = 'ccmadmin'
password = 'pswd'
client = Client(wsdl,location=location, transport=t)
resp = client.service.listDevicePool({'name':'%'},{'name':''})
print resp
**********************************************************************
The error that keeps popping up is following
Traceback (most recent call last):
File "C:\Users\Simran\Desktop\PythonScripts\CUCMDetails.py", line 36, in <module>
resp = client.service.listDevicePool({'name':'%'},{'name':''})
File "C:\Python27\lib\site-packages\suds\client.py", line 542, in __call__
return client.invoke(args, kwargs)
File "C:\Python27\lib\site-packages\suds\client.py", line 602, in invoke
result = self.send(soapenv)
File "C:\Python27\lib\site-packages\suds\client.py", line 637, in send
reply = transport.send(request)
File "C:\Python27\lib\site-packages\suds\transport\https.py", line 64, in send
return HttpTransport.send(self, request)
File "C:\Python27\lib\site-packages\suds\transport\http.py", line 77, in send
fp = self.u2open(u2request)
File "C:\Python27\lib\site-packages\suds\transport\http.py", line 118, in u2open
return url.open(u2request, timeout=tm)
File "C:\Python27\lib\urllib2.py", line 429, in open
response = self._open(req, data)
File "C:\Python27\lib\urllib2.py", line 447, in _open
'_open', req)
File "C:\Python27\lib\urllib2.py", line 407, in _call_chain
result = func(*args)
File "C:\Python27\lib\urllib2.py", line 1241, in https_open
context=self._context)
File "C:\Python27\lib\urllib2.py", line 1198, in do_open
raise URLError(err)
URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:661)>
>>>
08-07-2017 11:03 AM
It looks like the attempt to disable certificate checking for the SSL connection is not working in your code. It appears that suds does not include a simple way to disable cert checking.
Here is a similar example that has some info on actually using cert checking (which should be best practice anyway:)
08-12-2017 09:27 AM
Yes.. you are right...I've made some more modifications in the script & now I get an error about DH keys being too small. One way or the other, it never gets past certificate authentication point.
But I don't see anyone here facing such issues... they all seem to run the same script & get the desired results which makes me wonder if I am skipping something basic and why is it behaving this way in my case. Any help in that regards will be very useful because I am at a dead end & don't know what to follow now.
I'll try the cert checking method given in the link & see if it results in something different. Thanks very much for that.
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