{"id":38681251,"url":"https://github.com/awetomate/cucmapi","last_synced_at":"2026-01-17T10:13:44.516Z","repository":{"id":60786633,"uuid":"544940934","full_name":"awetomate/cucmapi","owner":"awetomate","description":"A SDK to simplify the work with Cisco Unified Communications Manager's various APIs","archived":false,"fork":false,"pushed_at":"2022-10-06T13:03:40.000Z","size":722,"stargazers_count":5,"open_issues_count":2,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-01-07T14:26:36.793Z","etag":null,"topics":["api","callmanager","cisco","cucm","soap","zeep"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/awetomate.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-10-03T13:59:45.000Z","updated_at":"2025-12-15T17:38:06.000Z","dependencies_parsed_at":"2022-10-04T22:25:18.073Z","dependency_job_id":null,"html_url":"https://github.com/awetomate/cucmapi","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/awetomate/cucmapi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awetomate%2Fcucmapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awetomate%2Fcucmapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awetomate%2Fcucmapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awetomate%2Fcucmapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/awetomate","download_url":"https://codeload.github.com/awetomate/cucmapi/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awetomate%2Fcucmapi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28505862,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T06:57:29.758Z","status":"ssl_error","status_checked_at":"2026-01-17T06:56:03.931Z","response_time":85,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","callmanager","cisco","cucm","soap","zeep"],"created_at":"2026-01-17T10:13:44.461Z","updated_at":"2026-01-17T10:13:44.508Z","avatar_url":"https://github.com/awetomate.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cucmapi\n\nThe cucmapi package is inspired by Levensailor's [ciscoaxl](https://github.com/levensailor/ciscoaxl), Presidio's [ciscoris](https://github.com/PresidioCode/ciscoris), and Jonathanelscpt's [ciscocucmapi](https://github.com/jonathanelscpt/ciscocucmapi).\n\ncucmapi runs on [python-zeep](https://docs.python-zeep.org/en/master/) and offers a complete abstraction from the AXL SOAP API and XML.  \nThe package gives you access to all API calls defined in the WSDL file.  \nCurrently, only Python 3.6+ is supported.\n\nWhile not Pythonic, I chose to keep all the method names as they are defined in the AXL schema reference, instead of turning them into snake-case variants, to have a 1:1 match between the available methods in this package and Cisco's documentation; i.e. if the WSDL operation is called addSipProfile then the method is called addSipProfile, too.  \n\n## Official Cisco API Documentation\n\n- AXL: https://developer.cisco.com/docs/axl-schema-reference/\n- RisPort70 API: https://developer.cisco.com/docs/sxml/#!risport70-api-reference\n- Control Center Services API: https://developer.cisco.com/docs/sxml/#!control-center-services-api-reference\n- Log Collection API: https://developer.cisco.com/docs/sxml/#!log-collection-and-dimegetfileservice-api-reference\n- CDRonDemand API: https://developer.cisco.com/docs/sxml/#!cdrondemand-api-reference\n- PerfMon API: https://developer.cisco.com/docs/sxml/#!perfmon-api-reference\n\n## Installation\n\n```bash\ngit clone git@github.com:awetomate/cucmapi.git\n```\n\nTesting in a lab is highly recommended. You can reserve a DevNet [Sandbox](https://developer.cisco.com/site/sandbox/) free of charge!\n\n___\n\n\n## Enable AXL SOAP Service on CUCM:\n\nEnable the AXL SOAP interface\n\nBrowse to the CUCM Serviceability page on https://\u003cIP_CUCM\u003e/ccmservice\n\nTools \u003e Service Activation:\n\nEnable the \"Cisco AXL Web Service\"\n![](https://pubhub.devnetcloud.com/media/axl/docs/authentication/assets/activation.png#developer.cisco.com)\n\n---\n\n## Create an AXL Service Account\n\n\u003e Step 1 - Create an AXL User Group\n\nCUCM \u003e User Management \u003e User Group \u003e Add.\n\n\u003e Step 2 - Assign the AXL role to the group\n\nOn the top right drop down list \"Related Links\". \n\nSelect \"Assign Role to User Group\" and \n- for full Read/Write access, select:\n  \"Standard AXL API Access\" \n- for Read-Only access, select \"Standard AXL API Users\" and \"Standard AXL Read Only API Access\"\n\n\u003e Step 3 - Create a new Application User\n\nCUCM \u003e User Management \u003e Application User \u003e Add.\n\nAdd the new User Group you created in step 1 and 2 to this user.\n\n## Quick Start\n```python\nfrom cucmapi import axl, ris, ccs, log, cdr, pfm\n\nusername = \"username\"\npassword = \"supersecret\"\ncucm = \"fqdn\" #or IP address\ncucm_version = \"11.5\"\nAXL = axl(username=username, password=password, cucm=cucm, cucm_version=cucm_version) # for SOAP AXL\nRIS = ris(username=username, password=password, cucm=cucm, cucm_version=cucm_version) # for RisPort70\nCCS = ccs(username=username, password=password, cucm=cucm, cucm_version=cucm_version) # for Control Center Services\nLOG = log(username=username, password=password, cucm=cucm, cucm_version=cucm_version) # for Log Collection\nCDR = cdr(username=username, password=password, cucm=cucm, cucm_version=cucm_version) # for CDRonDemand\nPFM = pfm(username=username, password=password, cucm=cucm, cucm_version=cucm_version) # for PerfMon\n\n# get phone\nphone = AXL.getPhone(name=\"CSFjohn\")\nprint(phone.description)\n\u003e\u003e\u003e\nJohns test description\n\u003e\u003e\u003e\n# update phone description\nAXL.updatePhone(name=\"CSFjohn\", description=\"Johns proper phone description\")\n# verify the new description has been set\nphone = AXL.getPhone(name=\"CSFjohn\")\nprint(phone.description)\n\u003e\u003e\u003e\nJohns proper phone description\n\u003e\u003e\u003e\n\n# get phone registration from RIS \u003e requires a list of devices as input and returns a list\n# if no list of subscribers is provided, all nodes in the cluster are queried\nreg = RIS.selectCmDeviceExt(devices=[\"CSFjohn\"])\nprint(reg[0].Status)\n\u003e\u003e\u003e\nRegistered\n\u003e\u003e\u003e\n\n# delete phone\nAXL.removePhone(name=\"CSFjohn\")\n\n# implicit \"return all\" will all available returnedTags\n# use sparingly and avoid on larger clusters (limit the returnedTags to what you need)\nall_devices = AXL.listPhone()\n\n```\n\n```python\n# Usecase Example 1: Find out if there are still some registered Cisco IP Communicators (end of support)\n\n# Step 1, get process node names, exlude the entry called 'EnterpriseWideData' \n# This is optional. If you don't provide a list of subs in step3 all nodes in the cluster are queried\nnode_names = [node.name for node in AXL.listProcessNode(returnedTags={\"name\": \"\"}) if \"Enterprise\" not in node.name]\n\n# Step 2, get a list of all Cisco IP Communicators via Thin SQL \u003e returns list of dictionaries\ncipcs = AXL.executeSQLQuery(sql=\"SELECT name FROM device WHERE tkclass=1 and tkmodel=30016\")\ndevice_names = [ipc[\"name\"] for ipc in cipcs]\n\n# Alternative to step 2 using axl\nphone_list = AXL.listPhone(returnedTags={\"name\": \"\", \"model\": \"\"})\ndevice_names = [phone.name for phone in phone_list if \"Communicator\" in phone.model]\n\n# Step 3, find all 'Registered' devices via RIS\nregistration = RIS.selectCmDeviceExt(devices=device_names, subs=node_names, status=\"Registered\")\n# or\nregistration = RIS.selectCmDeviceExt(devices=device_names, status=\"Registered\")\n\n```\n\n```python\n# Usecase Example 2: Get services status for each node in the cluster\n\n# Step 1, get the process node names plus the nodeUsage; exlude the entry called 'EnterpriseWideData' \nnode_names = AXL.listProcessNode(returnedTags={\"name\": \"\",\"nodeUsage\": \"\"})\nnodes = [{\"name\": node.name, \"nodeUsage\": node.nodeUsage} for node in node_names if \"Enterprise\" not in node.name]\n\n# Step 2, get the services info for each of the nodes and add them to the services list\nservices = []\nfor node in nodes:\n    # create a Control Center Services client instance for each node\n    CCS = ccs(username=username, password=password, cucm=node[\"name\"], cucm_version=version)\n    # get the services for the node\n    services_status = CCS.soapGetServiceStatus()\n    # Optional: create your own custom view and replace the ReasonCodes with 'Activated/Deactivated'\n    services_clean = [\n        {\"ServerName\": node[\"name\"],\n        \"NodeType\": node[\"nodeUsage\"],\n        \"ServiceName\": s.ServiceName,\n        \"ServiceStatus\": s.ServiceStatus,\n        \"ActivationStatus\": \"Activated\" if \"Service Not Activated\" not in s.ReasonCodeString else \"Deactivated\",\n        \"StartTime\": \"\" if not s.StartTime else s.StartTime\n        } for s in services_status]\n    # add the node's services to the services list\n    services += services_clean\n\n# now you have a list of all services for each node in the cluster\nprint(services)\n\u003e\u003e\u003e\n[{'ServerName': 'servernode01.domain.com',\n  'NodeType': 'Subscriber',\n  'ServiceName': 'A Cisco DB',\n  'ServiceStatus': 'Started',\n  'ActivationStatus': 'Activated',\n  'StartTime': 'Sat Nov 20 18:40:52 2021'},\n {'ServerName': 'servernode01.domain.com',\n  'NodeType': 'Subscriber',\n  'ServiceName': 'A Cisco DB Replicator',\n  'ServiceStatus': 'Started',\n  'ActivationStatus': 'Activated',\n  'StartTime': 'Sat Nov 20 18:40:53 2021'},\n {'ServerName': 'servernode01.domain.com',\n  'NodeType': 'Subscriber',\n  'ServiceName': 'Cisco AMC Service',\n  'ServiceStatus': 'Started',\n  'ActivationStatus': 'Activated',\n  'StartTime': 'Sat Nov 20 18:41:53 2021'},\n  ...\n  ]\n\u003e\u003e\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawetomate%2Fcucmapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fawetomate%2Fcucmapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawetomate%2Fcucmapi/lists"}