Cisco AXL updatePhone using python3, suds, SOAP Requests

1.6k views Asked by At

I now got a few SOAP request against my UCM 11.5 test environment working. But i'm struggeling with this one: Update Phone.

import ssl
from suds.client import Client

ssl._create_default_https_context = ssl._create_unverified_context
username = 'Administrator'
passwd = 'Password'
wsdl_url = 'http://host.domain.com/axlsqltoolkit/schema/11.5/AXLAPI.wsdl'
service_url = 'https://host.domain.com/axl/'
cucm_server = Client(wsdl_url, location = service_url, username=username, password=passwd)

def UpdatePhoneByName(cucm_server):
    result = cucm_server.service.updatePhone({'name': 'SEP0023331B4DBB','description': 'Haasdfllo'})
    print(result)
    return
UpdatePhoneByName(cucm_server)

I get the following result:

suds.TypeNotFound: Type not found: 'name'

I will also include output of cucm_server but only updatePhone part.

updatePhone(ns0:String100 name, ns0:XUUID uuid, ns0:UniqueString128 newName, ns0:String128 description, ns0:XFkType callingSearchSpaceName, ns0:XFkType devicePoolName, ns0:XFkType commonDeviceConfigName, ns0:XFkType commonPhoneConfigName, ns0:XNetworkLocation networkLocation, ns0:XFkType locationName, ns0:XFkType mediaResourceListName, ns0:XMOHAudioSourceId networkHoldMohAudioSourceId, ns0:XMOHAudioSourceId userHoldMohAudioSourceId, ns0:XFkType automatedAlternateRoutingCssName, ns0:XFkType aarNeighborhoodName, ns0:XLoadInformation loadInformation, ns0:XVendorConfig vendorConfig, ns0:String128 versionStamp, ns0:boolean traceFlag, ns0:String128 mlppDomainId, ns0:XStatus mlppIndicationStatus, ns0:XPreemption preemption, ns0:XStatus useTrustedRelayPoint, ns0:boolean retryVideoCallAsAudio, ns0:XFkType securityProfileName, ns0:XFkType sipProfileName, ns0:XFkType cgpnTransformationCssName, ns0:boolean useDevicePoolCgpnTransformCss, ns0:XFkType geoLocationName, ns0:XFkType geoLocationFilterName, ns0:boolean sendGeoLocation, ns0:removeLines removeLines, ns0:addLines addLines, ns0:lines lines, ns0:XFkType phoneTemplateName, ns0:speeddials speeddials, ns0:busyLampFields busyLampFields, ns0:XFkType primaryPhoneName, ns0:XStatus ringSettingIdleBlfAudibleAlert, ns0:XStatus ringSettingBusyBlfAudibleAlert, ns0:blfDirectedCallParks blfDirectedCallParks, ns0:addOnModules addOnModules, ns0:XUserLocale userLocale, ns0:XCountry networkLocale, ns0:XInteger idleTimeout, xs:string authenticationUrl, xs:string directoryUrl, xs:string idleUrl, xs:string informationUrl, xs:string messagesUrl, xs:string proxyServerUrl, xs:string servicesUrl, ns0:services services, ns0:XFkType softkeyTemplateName, ns0:XFkType defaultProfileName, ns0:boolean enableExtensionMobility, ns0:XBarge singleButtonBarge, ns0:XStatus joinAcrossLines, ns0:XStatus builtInBridgeStatus, ns0:XStatus callInfoPrivacyStatus, ns0:XStatus hlogStatus, ns0:XFkType ownerUserName, ns0:boolean ignorePresentationIndicators, ns0:XPacketCaptureMode packetCaptureMode, ns0:XInteger packetCaptureDuration, ns0:XFkType subscribeCallingSearchSpaceName, ns0:XFkType rerouteCallingSearchSpaceName, ns0:boolean allowCtiControlFlag, ns0:XFkType presenceGroupName, ns0:boolean unattendedPort, ns0:boolean requireDtmfReception, ns0:boolean rfc2833Disabled, ns0:XCertificateOperation certificateOperation, ns0:XAuthenticationMode authenticationMode, ns0:XKeySize keySize, ns0:XKeyOrder keyOrder, ns0:XECKeySize ecKeySize, ns0:String128 authenticationString, xs:string upgradeFinishTime, ns0:XStatus deviceMobilityMode, ns0:boolean remoteDevice, ns0:XDNDOption dndOption, ns0:XRingSetting dndRingSetting, ns0:boolean dndStatus, ns0:boolean isActive, ns0:XFkType mobilityUserIdName, ns0:XPhonePersonalization phoneSuite, ns0:XPhoneServiceDisplay phoneServiceDisplay, ns0:boolean isProtected, ns0:boolean mtpRequired, ns0:XSIPCodec mtpPreferedCodec, ns0:XFkType dialRulesName, ns0:String50 sshUserId, ns0:String255 sshPwd, ns0:String255 digestUser, ns0:XOutboundCallRollover outboundCallRollover, ns0:boolean hotlineDevice, ns0:String255 secureInformationUrl, ns0:String255 secureDirectoryUrl, ns0:String255 secureMessageUrl, ns0:String255 secureServicesUrl, ns0:String255 secureAuthenticationUrl, ns0:String255 secureIdleUrl, ns0:XStatus alwaysUsePrimeLine, ns0:XStatus alwaysUsePrimeLineForVoiceMessage, ns0:XFkType featureControlPolicy, ns0:XDeviceTrustMode deviceTrustMode, ns0:boolean earlyOfferSupportForVoiceCall, ns0:boolean requireThirdPartyRegistration, ns0:boolean blockIncomingCallsWhenRoaming, xs:string homeNetworkId, ns0:boolean AllowPresentationSharingUsingBfcp, ns0:confidentialAccess confidentialAccess, ns0:boolean requireOffPremiseLocation, ns0:boolean allowiXApplicableMedia, ns0:XFkType cgpnIngressDN, ns0:boolean useDevicePoolCgpnIngressDN, ns0:String128 msisdn, ns0:boolean enableCallRoutingToRdWhenNoneIsActive, ns0:XFkType wifiHotspotProfile, ns0:XFkType wirelessLanProfileGroup, ns0:XFkType elinGroup)

I also tried with uuid, _uuid and _name but nothing seems to work.

Any help would be much appreciated.

3

There are 3 answers

1
Maresh On

Did you check the WSDL? Is it correct? Does it define 'name'?

Just had a quick look at the doc. Please include the output of print cucm_server to your question. According to what I see, methods take named parameters, just one dict.

I never got around to use suds anyways. I switched to Zeep a while back, it works like a charm.

0
user140635 On

I think the format is something like updatePhone = cucm_server.service.updatePhone(uuid=uuid, newName=newname, description= description)

0
jonathan On

Short answer:

Dump suds, it's not actively supported. Use zeep instead.

If you want a working sample for zeep, here it is:

# -*- coding: utf-8 -*-

from zeep import Client
from zeep.cache import SqliteCache
from zeep.transports import Transport
from requests import Session
from requests.auth import HTTPBasicAuth
import urllib3
from urllib3.exceptions import InsecureRequestWarning


urllib3.disable_warnings(InsecureRequestWarning)

USERNAME = 'administrator'
PASSWORD = 'ciscopsdt'
IP_ADDRESS = "123.123.123.123"
WSDL = 'file://C://path//to//schema//11.5//AXLAPI.wsdl'
BINDING_NAME = "{http://www.cisco.com/AXLAPIService/}AXLAPIBinding"
ADDRESS = "https://{ip}:8443/axl/".format(ip=IP_ADDRESS)


def update_phone_by_name(client, name, description):
    return client.updatePhone(**{'name': name, 'description': description})


def get_phone_by_name(client, name):
    return client.getPhone(name=name)


def main():
    session = Session()
    session.verify = False
    session.auth = HTTPBasicAuth(USERNAME, PASSWORD)
    transport = Transport(cache=SqliteCache(), session=session, timeout=60)
    client = Client(wsdl=WSDL, transport=transport)
    axl = client.create_service(BINDING_NAME, ADDRESS)

    update_phone_by_name(axl, "BOTUSER011", "update my description")
    print(get_phone_by_name(axl, "BOTUSER011"))


if __name__ == '__main__':
    main()

If, however, you must proceed with suds, here's a sample using suds-jurko:

# -*- coding: utf-8 -*-

import ssl
from suds.client import Client


ssl._create_default_https_context = ssl._create_unverified_context
username = 'administrator'
password = 'cisco'
wsdl_url = 'file:///C://path//to//schema//current//AXLAPI.wsdl'
service_url = 'https://123.123.123.123:8443/axl/'


def update_phone_by_name(client, name, description):
    return client.service.updatePhone(**{'name': name, 'description': description})


def get_phone_by_name(client, name):
    return client.service.getPhone(name=name)


def main():
    cucm_server = Client(wsdl_url, location=service_url, username=username, password=password)
    print(get_phone_by_name(cucm_server, 'BOTUSER011'))


if __name__ == '__main__':
    main()

If you look closely, you'll see that your error was due to sending a dictionary, instead of **kwargs in your function update_phone_by_name.