wxcli 1.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (413) hide show
  1. wxcli/__init__.py +4 -0
  2. wxcli/_playbook/.claude/agents/migration-advisor.md +239 -0
  3. wxcli/_playbook/.claude/agents/wxc-calling-builder.md +946 -0
  4. wxcli/_playbook/.claude/rules/cleanup.md +29 -0
  5. wxcli/_playbook/.claude/rules/cucm-migration.md +58 -0
  6. wxcli/_playbook/.claude/rules/org-health.md +14 -0
  7. wxcli/_playbook/.claude/settings.json +8 -0
  8. wxcli/_playbook/.claude/skills/audit-compliance/SKILL.md +515 -0
  9. wxcli/_playbook/.claude/skills/call-control/SKILL.md +747 -0
  10. wxcli/_playbook/.claude/skills/configure-features/SKILL.md +623 -0
  11. wxcli/_playbook/.claude/skills/configure-routing/SKILL.md +627 -0
  12. wxcli/_playbook/.claude/skills/contact-center/SKILL.md +1181 -0
  13. wxcli/_playbook/.claude/skills/cucm-migrate/SKILL.md +820 -0
  14. wxcli/_playbook/.claude/skills/customer-assist/SKILL.md +443 -0
  15. wxcli/_playbook/.claude/skills/device-platform/SKILL.md +407 -0
  16. wxcli/_playbook/.claude/skills/manage-call-settings/SKILL.md +757 -0
  17. wxcli/_playbook/.claude/skills/manage-devices/SKILL.md +790 -0
  18. wxcli/_playbook/.claude/skills/manage-identity/SKILL.md +638 -0
  19. wxcli/_playbook/.claude/skills/manage-licensing/SKILL.md +528 -0
  20. wxcli/_playbook/.claude/skills/manage-meetings/SKILL.md +708 -0
  21. wxcli/_playbook/.claude/skills/messaging-bots/SKILL.md +365 -0
  22. wxcli/_playbook/.claude/skills/messaging-spaces/SKILL.md +520 -0
  23. wxcli/_playbook/.claude/skills/org-health/SKILL.md +159 -0
  24. wxcli/_playbook/.claude/skills/provision-calling/SKILL.md +421 -0
  25. wxcli/_playbook/.claude/skills/query-live/SKILL.md +183 -0
  26. wxcli/_playbook/.claude/skills/query-live/domains/call-flow-trace.md +223 -0
  27. wxcli/_playbook/.claude/skills/query-live/domains/call-history.md +44 -0
  28. wxcli/_playbook/.claude/skills/query-live/domains/features.md +169 -0
  29. wxcli/_playbook/.claude/skills/query-live/domains/numbers.md +93 -0
  30. wxcli/_playbook/.claude/skills/query-live/domains/people-and-settings.md +146 -0
  31. wxcli/_playbook/.claude/skills/query-live/domains/routing.md +124 -0
  32. wxcli/_playbook/.claude/skills/reporting/SKILL.md +501 -0
  33. wxcli/_playbook/.claude/skills/reporting/references/cdr-recipes.md +1628 -0
  34. wxcli/_playbook/.claude/skills/reporting-cc/SKILL.md +251 -0
  35. wxcli/_playbook/.claude/skills/reporting-meetings/SKILL.md +290 -0
  36. wxcli/_playbook/.claude/skills/teardown/SKILL.md +214 -0
  37. wxcli/_playbook/.claude/skills/video-mesh/SKILL.md +379 -0
  38. wxcli/_playbook/.claude/skills/wxc-calling-debug/SKILL.md +475 -0
  39. wxcli/_playbook/CLAUDE.md +373 -0
  40. wxcli/_playbook/docs/reference/CLAUDE.md +25 -0
  41. wxcli/_playbook/docs/reference/admin-apps-data.md +643 -0
  42. wxcli/_playbook/docs/reference/admin-audit-security.md +322 -0
  43. wxcli/_playbook/docs/reference/admin-hybrid.md +383 -0
  44. wxcli/_playbook/docs/reference/admin-identity-scim.md +1007 -0
  45. wxcli/_playbook/docs/reference/admin-licensing.md +414 -0
  46. wxcli/_playbook/docs/reference/admin-org-management.md +586 -0
  47. wxcli/_playbook/docs/reference/admin-partner.md +357 -0
  48. wxcli/_playbook/docs/reference/archive/wxc-sdk-patterns.md +1229 -0
  49. wxcli/_playbook/docs/reference/archive/wxcadm-advanced.md +835 -0
  50. wxcli/_playbook/docs/reference/archive/wxcadm-core.md +743 -0
  51. wxcli/_playbook/docs/reference/archive/wxcadm-devices-workspaces.md +1305 -0
  52. wxcli/_playbook/docs/reference/archive/wxcadm-features.md +849 -0
  53. wxcli/_playbook/docs/reference/archive/wxcadm-locations.md +938 -0
  54. wxcli/_playbook/docs/reference/archive/wxcadm-person.md +1255 -0
  55. wxcli/_playbook/docs/reference/archive/wxcadm-routing.md +1262 -0
  56. wxcli/_playbook/docs/reference/authentication.md +965 -0
  57. wxcli/_playbook/docs/reference/call-control.md +1205 -0
  58. wxcli/_playbook/docs/reference/call-features-additional.md +2541 -0
  59. wxcli/_playbook/docs/reference/call-features-major.md +1320 -0
  60. wxcli/_playbook/docs/reference/call-routing.md +2304 -0
  61. wxcli/_playbook/docs/reference/contact-center-analytics.md +1049 -0
  62. wxcli/_playbook/docs/reference/contact-center-core.md +1614 -0
  63. wxcli/_playbook/docs/reference/contact-center-journey.md +457 -0
  64. wxcli/_playbook/docs/reference/contact-center-routing.md +1138 -0
  65. wxcli/_playbook/docs/reference/devices-core.md +1869 -0
  66. wxcli/_playbook/docs/reference/devices-dect.md +1150 -0
  67. wxcli/_playbook/docs/reference/devices-platform.md +467 -0
  68. wxcli/_playbook/docs/reference/devices-workspaces.md +1426 -0
  69. wxcli/_playbook/docs/reference/emergency-services.md +1122 -0
  70. wxcli/_playbook/docs/reference/location-calling-core.md +2037 -0
  71. wxcli/_playbook/docs/reference/location-calling-media.md +1334 -0
  72. wxcli/_playbook/docs/reference/location-recording-advanced.md +1482 -0
  73. wxcli/_playbook/docs/reference/meetings-content.md +473 -0
  74. wxcli/_playbook/docs/reference/meetings-core.md +903 -0
  75. wxcli/_playbook/docs/reference/meetings-infrastructure.md +899 -0
  76. wxcli/_playbook/docs/reference/meetings-settings.md +850 -0
  77. wxcli/_playbook/docs/reference/messaging-bots.md +1091 -0
  78. wxcli/_playbook/docs/reference/messaging-spaces.md +695 -0
  79. wxcli/_playbook/docs/reference/person-call-settings-behavior.md +1639 -0
  80. wxcli/_playbook/docs/reference/person-call-settings-handling.md +1394 -0
  81. wxcli/_playbook/docs/reference/person-call-settings-media.md +1898 -0
  82. wxcli/_playbook/docs/reference/person-call-settings-permissions.md +1329 -0
  83. wxcli/_playbook/docs/reference/provisioning.md +1366 -0
  84. wxcli/_playbook/docs/reference/reporting-analytics.md +1318 -0
  85. wxcli/_playbook/docs/reference/self-service-call-settings.md +1020 -0
  86. wxcli/_playbook/docs/reference/virtual-lines.md +1132 -0
  87. wxcli/_playbook/docs/reference/webhooks-events.md +1444 -0
  88. wxcli/_playbook/docs/reference/wxcadm-xsi-realtime.md +953 -0
  89. wxcli/_version.py +24 -0
  90. wxcli/auth.py +137 -0
  91. wxcli/commands/__init__.py +0 -0
  92. wxcli/commands/_registry.py +181 -0
  93. wxcli/commands/activation_email.py +103 -0
  94. wxcli/commands/admin_recordings.py +585 -0
  95. wxcli/commands/analytics.py +105 -0
  96. wxcli/commands/announcement_playlists.py +219 -0
  97. wxcli/commands/announcements.py +519 -0
  98. wxcli/commands/archive_users.py +36 -0
  99. wxcli/commands/attachment_actions.py +60 -0
  100. wxcli/commands/audit_events.py +83 -0
  101. wxcli/commands/authorizations.py +113 -0
  102. wxcli/commands/auto_attendant.py +642 -0
  103. wxcli/commands/broadworks_billing_reports.py +126 -0
  104. wxcli/commands/broadworks_enterprises.py +160 -0
  105. wxcli/commands/broadworks_subscribers.py +319 -0
  106. wxcli/commands/broadworks_workspaces.py +108 -0
  107. wxcli/commands/call_controls.py +1304 -0
  108. wxcli/commands/call_park.py +494 -0
  109. wxcli/commands/call_pickup.py +229 -0
  110. wxcli/commands/call_queue.py +1878 -0
  111. wxcli/commands/call_recording.py +707 -0
  112. wxcli/commands/call_routing.py +1610 -0
  113. wxcli/commands/call_settings_for_me_phase_5.py +212 -0
  114. wxcli/commands/caller_reputation.py +169 -0
  115. wxcli/commands/calling_service.py +305 -0
  116. wxcli/commands/cc_address_book.py +770 -0
  117. wxcli/commands/cc_agent_greetings.py +242 -0
  118. wxcli/commands/cc_agent_summaries.py +39 -0
  119. wxcli/commands/cc_agent_wellbeing.py +216 -0
  120. wxcli/commands/cc_agents.py +425 -0
  121. wxcli/commands/cc_ai_assistant.py +55 -0
  122. wxcli/commands/cc_ai_feature.py +294 -0
  123. wxcli/commands/cc_audio_files.py +149 -0
  124. wxcli/commands/cc_auto_csat.py +311 -0
  125. wxcli/commands/cc_aux_code.py +458 -0
  126. wxcli/commands/cc_business_hour.py +353 -0
  127. wxcli/commands/cc_call_monitoring.py +228 -0
  128. wxcli/commands/cc_callbacks.py +194 -0
  129. wxcli/commands/cc_campaign.py +212 -0
  130. wxcli/commands/cc_captures.py +39 -0
  131. wxcli/commands/cc_contact_list.py +169 -0
  132. wxcli/commands/cc_contact_number.py +295 -0
  133. wxcli/commands/cc_data_sources.py +235 -0
  134. wxcli/commands/cc_desktop_layout.py +380 -0
  135. wxcli/commands/cc_desktop_profile.py +322 -0
  136. wxcli/commands/cc_dial_number.py +511 -0
  137. wxcli/commands/cc_dial_plan.py +347 -0
  138. wxcli/commands/cc_dnc.py +101 -0
  139. wxcli/commands/cc_entry_point.py +545 -0
  140. wxcli/commands/cc_ewt.py +51 -0
  141. wxcli/commands/cc_flow.py +477 -0
  142. wxcli/commands/cc_global_vars.py +430 -0
  143. wxcli/commands/cc_holiday_list.py +335 -0
  144. wxcli/commands/cc_journey.py +1261 -0
  145. wxcli/commands/cc_legacy_flows.py +49 -0
  146. wxcli/commands/cc_multimedia_profile.py +436 -0
  147. wxcli/commands/cc_notification.py +51 -0
  148. wxcli/commands/cc_outdial_ani.py +604 -0
  149. wxcli/commands/cc_overrides.py +341 -0
  150. wxcli/commands/cc_queue.py +1083 -0
  151. wxcli/commands/cc_queue_stats.py +55 -0
  152. wxcli/commands/cc_realtime.py +51 -0
  153. wxcli/commands/cc_resource_collection.py +312 -0
  154. wxcli/commands/cc_search.py +46 -0
  155. wxcli/commands/cc_site.py +400 -0
  156. wxcli/commands/cc_skill.py +350 -0
  157. wxcli/commands/cc_skill_profile.py +289 -0
  158. wxcli/commands/cc_subscriptions.py +426 -0
  159. wxcli/commands/cc_summaries.py +130 -0
  160. wxcli/commands/cc_tasks.py +844 -0
  161. wxcli/commands/cc_team.py +325 -0
  162. wxcli/commands/cc_user_profiles.py +349 -0
  163. wxcli/commands/cc_users.py +701 -0
  164. wxcli/commands/cc_work_types.py +363 -0
  165. wxcli/commands/cdr.py +89 -0
  166. wxcli/commands/classifications.py +38 -0
  167. wxcli/commands/cleanup.py +1427 -0
  168. wxcli/commands/client_settings.py +72 -0
  169. wxcli/commands/conference.py +328 -0
  170. wxcli/commands/configure.py +72 -0
  171. wxcli/commands/converged_recordings.py +347 -0
  172. wxcli/commands/converged_recordings_export.py +310 -0
  173. wxcli/commands/cq_playlists.py +42 -0
  174. wxcli/commands/cucm.py +2794 -0
  175. wxcli/commands/cucm_config.py +129 -0
  176. wxcli/commands/customer_assist.py +373 -0
  177. wxcli/commands/data_sources.py +227 -0
  178. wxcli/commands/dect_devices.py +787 -0
  179. wxcli/commands/device_configurations.py +77 -0
  180. wxcli/commands/device_dynamic_settings.py +320 -0
  181. wxcli/commands/device_settings.py +1489 -0
  182. wxcli/commands/devices.py +280 -0
  183. wxcli/commands/domains.py +142 -0
  184. wxcli/commands/ecm.py +178 -0
  185. wxcli/commands/emergency_services.py +827 -0
  186. wxcli/commands/events.py +83 -0
  187. wxcli/commands/external_voicemail.py +52 -0
  188. wxcli/commands/groups.py +206 -0
  189. wxcli/commands/guest_management.py +76 -0
  190. wxcli/commands/hds.py +340 -0
  191. wxcli/commands/hot_desk.py +67 -0
  192. wxcli/commands/hot_desking_members.py +118 -0
  193. wxcli/commands/hot_desking_portal.py +124 -0
  194. wxcli/commands/hunt_group.py +577 -0
  195. wxcli/commands/hybrid_clusters.py +71 -0
  196. wxcli/commands/hybrid_connectors.py +67 -0
  197. wxcli/commands/identity_org.py +159 -0
  198. wxcli/commands/init_playbook.py +155 -0
  199. wxcli/commands/licenses.py +106 -0
  200. wxcli/commands/live_monitoring.py +40 -0
  201. wxcli/commands/location_call_handling.py +577 -0
  202. wxcli/commands/location_schedules.py +341 -0
  203. wxcli/commands/location_settings.py +1297 -0
  204. wxcli/commands/location_voicemail.py +494 -0
  205. wxcli/commands/locations.py +336 -0
  206. wxcli/commands/meeting_captions.py +110 -0
  207. wxcli/commands/meeting_chats.py +63 -0
  208. wxcli/commands/meeting_invitees.py +234 -0
  209. wxcli/commands/meeting_messages.py +28 -0
  210. wxcli/commands/meeting_participants.py +278 -0
  211. wxcli/commands/meeting_polls.py +111 -0
  212. wxcli/commands/meeting_preferences.py +515 -0
  213. wxcli/commands/meeting_qa.py +78 -0
  214. wxcli/commands/meeting_qualities.py +43 -0
  215. wxcli/commands/meeting_reports.py +101 -0
  216. wxcli/commands/meeting_session_types.py +105 -0
  217. wxcli/commands/meeting_site.py +57 -0
  218. wxcli/commands/meeting_slido.py +44 -0
  219. wxcli/commands/meeting_summaries.py +92 -0
  220. wxcli/commands/meeting_tracking_codes.py +233 -0
  221. wxcli/commands/meeting_transcripts.py +230 -0
  222. wxcli/commands/meetings.py +1997 -0
  223. wxcli/commands/memberships.py +164 -0
  224. wxcli/commands/messages.py +213 -0
  225. wxcli/commands/mode_management.py +244 -0
  226. wxcli/commands/my_call_settings.py +3577 -0
  227. wxcli/commands/numbers.py +405 -0
  228. wxcli/commands/operating_modes.py +410 -0
  229. wxcli/commands/org_contacts.py +284 -0
  230. wxcli/commands/org_health_cli.py +55 -0
  231. wxcli/commands/org_settings.py +71 -0
  232. wxcli/commands/organizations.py +83 -0
  233. wxcli/commands/paging_group.py +257 -0
  234. wxcli/commands/partner_admins.py +141 -0
  235. wxcli/commands/partner_reports.py +188 -0
  236. wxcli/commands/partner_tags.py +216 -0
  237. wxcli/commands/people.py +279 -0
  238. wxcli/commands/person_call_settings.py +71 -0
  239. wxcli/commands/pstn.py +280 -0
  240. wxcli/commands/recording_report.py +154 -0
  241. wxcli/commands/report_templates.py +38 -0
  242. wxcli/commands/reports.py +144 -0
  243. wxcli/commands/resource_group_memberships.py +160 -0
  244. wxcli/commands/resource_groups.py +67 -0
  245. wxcli/commands/roles.py +63 -0
  246. wxcli/commands/room_tabs.py +160 -0
  247. wxcli/commands/rooms.py +225 -0
  248. wxcli/commands/scim_bulk.py +46 -0
  249. wxcli/commands/scim_groups.py +246 -0
  250. wxcli/commands/scim_schemas.py +82 -0
  251. wxcli/commands/scim_users.py +283 -0
  252. wxcli/commands/security_audit.py +54 -0
  253. wxcli/commands/service_apps.py +51 -0
  254. wxcli/commands/single_number_reach.py +209 -0
  255. wxcli/commands/team_memberships.py +155 -0
  256. wxcli/commands/teams.py +153 -0
  257. wxcli/commands/ucm_profile.py +42 -0
  258. wxcli/commands/update.py +219 -0
  259. wxcli/commands/user_settings.py +5116 -0
  260. wxcli/commands/video_mesh.py +1090 -0
  261. wxcli/commands/virtual_extensions.py +502 -0
  262. wxcli/commands/virtual_line_settings.py +2072 -0
  263. wxcli/commands/webhooks.py +176 -0
  264. wxcli/commands/wholesale_billing_reports.py +147 -0
  265. wxcli/commands/wholesale_provisioning.py +523 -0
  266. wxcli/commands/workspace_locations.py +339 -0
  267. wxcli/commands/workspace_metrics.py +103 -0
  268. wxcli/commands/workspace_personalization.py +70 -0
  269. wxcli/commands/workspace_settings.py +3347 -0
  270. wxcli/commands/workspaces.py +279 -0
  271. wxcli/commands/xapi.py +114 -0
  272. wxcli/config.py +139 -0
  273. wxcli/errors.py +77 -0
  274. wxcli/main.py +210 -0
  275. wxcli/migration/CLAUDE.md +106 -0
  276. wxcli/migration/__init__.py +1 -0
  277. wxcli/migration/advisory/CLAUDE.md +196 -0
  278. wxcli/migration/advisory/__init__.py +46 -0
  279. wxcli/migration/advisory/advisor.py +107 -0
  280. wxcli/migration/advisory/advisory_patterns.py +2552 -0
  281. wxcli/migration/advisory/recommendation_rules.py +835 -0
  282. wxcli/migration/cucm/CLAUDE.md +74 -0
  283. wxcli/migration/cucm/__init__.py +5 -0
  284. wxcli/migration/cucm/connection.py +265 -0
  285. wxcli/migration/cucm/discovery.py +225 -0
  286. wxcli/migration/cucm/extractors/__init__.py +1 -0
  287. wxcli/migration/cucm/extractors/announcements.py +92 -0
  288. wxcli/migration/cucm/extractors/base.py +90 -0
  289. wxcli/migration/cucm/extractors/device_profiles.py +98 -0
  290. wxcli/migration/cucm/extractors/devices.py +193 -0
  291. wxcli/migration/cucm/extractors/e911.py +103 -0
  292. wxcli/migration/cucm/extractors/features.py +309 -0
  293. wxcli/migration/cucm/extractors/helpers.py +73 -0
  294. wxcli/migration/cucm/extractors/informational.py +295 -0
  295. wxcli/migration/cucm/extractors/locations.py +221 -0
  296. wxcli/migration/cucm/extractors/moh.py +100 -0
  297. wxcli/migration/cucm/extractors/remote_destinations.py +96 -0
  298. wxcli/migration/cucm/extractors/routing.py +493 -0
  299. wxcli/migration/cucm/extractors/shared_lines.py +146 -0
  300. wxcli/migration/cucm/extractors/templates.py +229 -0
  301. wxcli/migration/cucm/extractors/tier4.py +173 -0
  302. wxcli/migration/cucm/extractors/users.py +240 -0
  303. wxcli/migration/cucm/extractors/voicemail.py +243 -0
  304. wxcli/migration/cucm/extractors/workspaces.py +88 -0
  305. wxcli/migration/cucm/unity_connection.py +304 -0
  306. wxcli/migration/execute/CLAUDE.md +372 -0
  307. wxcli/migration/execute/__init__.py +303 -0
  308. wxcli/migration/execute/batch.py +277 -0
  309. wxcli/migration/execute/dependency.py +483 -0
  310. wxcli/migration/execute/engine.py +964 -0
  311. wxcli/migration/execute/handlers.py +2232 -0
  312. wxcli/migration/execute/planner.py +1939 -0
  313. wxcli/migration/execute/runtime.py +571 -0
  314. wxcli/migration/export/CLAUDE.md +49 -0
  315. wxcli/migration/export/__init__.py +8 -0
  316. wxcli/migration/export/csv_export.py +126 -0
  317. wxcli/migration/export/deployment_plan.py +479 -0
  318. wxcli/migration/export/json_export.py +60 -0
  319. wxcli/migration/models.py +941 -0
  320. wxcli/migration/phone_models.py +50 -0
  321. wxcli/migration/preflight/CLAUDE.md +52 -0
  322. wxcli/migration/preflight/__init__.py +89 -0
  323. wxcli/migration/preflight/checks.py +911 -0
  324. wxcli/migration/preflight/runner.py +293 -0
  325. wxcli/migration/rate_limiter.py +144 -0
  326. wxcli/migration/report/CLAUDE.md +245 -0
  327. wxcli/migration/report/__init__.py +7 -0
  328. wxcli/migration/report/appendix.py +2437 -0
  329. wxcli/migration/report/assembler.py +183 -0
  330. wxcli/migration/report/charts.py +263 -0
  331. wxcli/migration/report/executive.py +776 -0
  332. wxcli/migration/report/explainer.py +704 -0
  333. wxcli/migration/report/helpers.py +74 -0
  334. wxcli/migration/report/ingest.py +152 -0
  335. wxcli/migration/report/notice_templates.py +192 -0
  336. wxcli/migration/report/score.py +375 -0
  337. wxcli/migration/report/styles.py +1052 -0
  338. wxcli/migration/report/user_diff.py +1052 -0
  339. wxcli/migration/report/user_notice.py +425 -0
  340. wxcli/migration/state.py +139 -0
  341. wxcli/migration/store.py +860 -0
  342. wxcli/migration/transform/CLAUDE.md +107 -0
  343. wxcli/migration/transform/__init__.py +12 -0
  344. wxcli/migration/transform/analysis_pipeline.py +453 -0
  345. wxcli/migration/transform/analyzers/__init__.py +142 -0
  346. wxcli/migration/transform/analyzers/css_permission.py +189 -0
  347. wxcli/migration/transform/analyzers/css_routing.py +335 -0
  348. wxcli/migration/transform/analyzers/device_compatibility.py +122 -0
  349. wxcli/migration/transform/analyzers/dn_ambiguity.py +131 -0
  350. wxcli/migration/transform/analyzers/duplicate_user.py +221 -0
  351. wxcli/migration/transform/analyzers/extension_conflict.py +173 -0
  352. wxcli/migration/transform/analyzers/feature_approximation.py +227 -0
  353. wxcli/migration/transform/analyzers/layout_overflow.py +174 -0
  354. wxcli/migration/transform/analyzers/location_ambiguity.py +184 -0
  355. wxcli/migration/transform/analyzers/missing_data.py +300 -0
  356. wxcli/migration/transform/analyzers/selective_call_handling.py +394 -0
  357. wxcli/migration/transform/analyzers/shared_line.py +170 -0
  358. wxcli/migration/transform/analyzers/voicemail_compatibility.py +267 -0
  359. wxcli/migration/transform/analyzers/workspace_license.py +212 -0
  360. wxcli/migration/transform/cross_reference.py +1136 -0
  361. wxcli/migration/transform/cucm_pattern.py +246 -0
  362. wxcli/migration/transform/decisions.py +301 -0
  363. wxcli/migration/transform/e164.py +145 -0
  364. wxcli/migration/transform/engine.py +256 -0
  365. wxcli/migration/transform/mappers/CLAUDE.md +123 -0
  366. wxcli/migration/transform/mappers/__init__.py +76 -0
  367. wxcli/migration/transform/mappers/announcement_mapper.py +122 -0
  368. wxcli/migration/transform/mappers/base.py +190 -0
  369. wxcli/migration/transform/mappers/button_template_mapper.py +186 -0
  370. wxcli/migration/transform/mappers/call_forwarding_mapper.py +228 -0
  371. wxcli/migration/transform/mappers/call_settings_mapper.py +144 -0
  372. wxcli/migration/transform/mappers/css_mapper.py +868 -0
  373. wxcli/migration/transform/mappers/dect_mapper.py +367 -0
  374. wxcli/migration/transform/mappers/device_layout_mapper.py +289 -0
  375. wxcli/migration/transform/mappers/device_mapper.py +227 -0
  376. wxcli/migration/transform/mappers/device_profile_mapper.py +190 -0
  377. wxcli/migration/transform/mappers/device_settings_mapper.py +464 -0
  378. wxcli/migration/transform/mappers/e911_mapper.py +129 -0
  379. wxcli/migration/transform/mappers/ecbn_mapper.py +263 -0
  380. wxcli/migration/transform/mappers/executive_assistant_mapper.py +156 -0
  381. wxcli/migration/transform/mappers/feature_mapper.py +1179 -0
  382. wxcli/migration/transform/mappers/line_mapper.py +310 -0
  383. wxcli/migration/transform/mappers/location_mapper.py +235 -0
  384. wxcli/migration/transform/mappers/moh_mapper.py +114 -0
  385. wxcli/migration/transform/mappers/monitoring_mapper.py +221 -0
  386. wxcli/migration/transform/mappers/receptionist_mapper.py +245 -0
  387. wxcli/migration/transform/mappers/routing_mapper.py +821 -0
  388. wxcli/migration/transform/mappers/snr_mapper.py +201 -0
  389. wxcli/migration/transform/mappers/softkey_mapper.py +205 -0
  390. wxcli/migration/transform/mappers/user_mapper.py +264 -0
  391. wxcli/migration/transform/mappers/voicemail_group_mapper.py +286 -0
  392. wxcli/migration/transform/mappers/voicemail_mapper.py +514 -0
  393. wxcli/migration/transform/mappers/workspace_mapper.py +464 -0
  394. wxcli/migration/transform/normalizers.py +2008 -0
  395. wxcli/migration/transform/pattern_converter.py +106 -0
  396. wxcli/migration/transform/pipeline.py +271 -0
  397. wxcli/migration/transform/rules.py +255 -0
  398. wxcli/org_health/CLAUDE.md +63 -0
  399. wxcli/org_health/__init__.py +7 -0
  400. wxcli/org_health/analyze.py +93 -0
  401. wxcli/org_health/checks.py +458 -0
  402. wxcli/org_health/collector.py +62 -0
  403. wxcli/org_health/models.py +78 -0
  404. wxcli/org_health/report.py +300 -0
  405. wxcli/output.py +101 -0
  406. wxcli-1.2.0.dist-info/METADATA +505 -0
  407. wxcli-1.2.0.dist-info/RECORD +413 -0
  408. wxcli-1.2.0.dist-info/WHEEL +5 -0
  409. wxcli-1.2.0.dist-info/entry_points.txt +2 -0
  410. wxcli-1.2.0.dist-info/licenses/LICENSE +191 -0
  411. wxcli-1.2.0.dist-info/scm_file_list.json +751 -0
  412. wxcli-1.2.0.dist-info/scm_version.json +8 -0
  413. wxcli-1.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,410 @@
1
+ import json
2
+ import typer
3
+ from wxcli.auth import get_api
4
+ from wxcli.errors import WebexError, handle_rest_error
5
+ from wxcli.output import print_table, print_json
6
+ from wxcli.config import get_org_id
7
+
8
+
9
+ app = typer.Typer(help="Manage Webex Calling operating-modes.")
10
+
11
+
12
+ @app.command("list")
13
+ def cmd_list(
14
+ name: str = typer.Option(None, "--name", help="List `operating modes` whose name contains this string."),
15
+ limit_to_location_id: str = typer.Option(None, "--limit-to-location-id", help="Location query parameter to filter the `operating modes` fro"),
16
+ limit_to_org_level_enabled: str = typer.Option(None, "--limit-to-org-level-enabled", help="If true, only return `operating modes` defined at the organi"),
17
+ order: str = typer.Option(None, "--order", help="Sort the list of `operating modes` based on `name`, either a"),
18
+ output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
19
+ limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
20
+ offset: int = typer.Option(0, "--offset", help="Start offset"),
21
+ debug: bool = typer.Option(False, "--debug"),
22
+ ):
23
+ """Read the List of Operating Modes."""
24
+ api = get_api(debug=debug)
25
+ url = f"https://webexapis.com/v1/telephony/config/operatingModes"
26
+ params = {}
27
+ if name is not None:
28
+ params["name"] = name
29
+ if limit_to_location_id is not None:
30
+ params["limitToLocationId"] = limit_to_location_id
31
+ if limit_to_org_level_enabled is not None:
32
+ params["limitToOrgLevelEnabled"] = limit_to_org_level_enabled
33
+ if order is not None:
34
+ params["order"] = order
35
+ if limit > 0:
36
+ params["max"] = limit
37
+ if offset > 0:
38
+ params["start"] = offset
39
+ org_id = get_org_id()
40
+ if org_id is not None:
41
+ params["orgId"] = org_id
42
+ result = None
43
+ try:
44
+ result = api.session.rest_get(url, params=params)
45
+ except WebexError as e:
46
+ handle_rest_error(e)
47
+ result = result or []
48
+ items = result.get("operatingModes", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
49
+ if output == "json":
50
+ print_json(items)
51
+ else:
52
+ print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
53
+
54
+
55
+
56
+ @app.command("show")
57
+ def show(
58
+ mode_id: str = typer.Argument(help="modeId"),
59
+ output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
60
+ debug: bool = typer.Option(False, "--debug"),
61
+ ):
62
+ """Get Details for an Operating Mode."""
63
+ api = get_api(debug=debug)
64
+ url = f"https://webexapis.com/v1/telephony/config/operatingModes/{mode_id}"
65
+ params = {}
66
+ org_id = get_org_id()
67
+ if org_id is not None:
68
+ params["orgId"] = org_id
69
+ try:
70
+ result = api.session.rest_get(url, params=params)
71
+ except WebexError as e:
72
+ handle_rest_error(e)
73
+ if output == "json":
74
+ print_json(result)
75
+ else:
76
+ if isinstance(result, dict):
77
+ print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
78
+ elif isinstance(result, list):
79
+ print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
80
+ else:
81
+ print_json(result)
82
+
83
+
84
+
85
+ @app.command("update")
86
+ def update(
87
+ mode_id: str = typer.Argument(help="modeId"),
88
+ name: str = typer.Option(None, "--name", help="New unique name for the `operating mode`."),
89
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
90
+ debug: bool = typer.Option(False, "--debug"),
91
+ ):
92
+ """Modify an Operating Mode\n\nExample --json-body:\n '{"name":"...","sameHoursDaily":{"mondayToFriday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."},"saturdayToSunday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."}},"differentHoursDaily":{"sunday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."},"monday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."},"tuesday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."},"wednesday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."},"thursday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."},"friday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."},"saturday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."}},"holidays":[{"name":"...","allDayEnabled":"...","startDate":"...","endDate":"...","startTime":"...","endTime":"...","recurrence":"..."}],"callForwarding":{"enabled":true,"destination":"...","destinationVoicemailEnabled":true}}'."""
93
+ api = get_api(debug=debug)
94
+ url = f"https://webexapis.com/v1/telephony/config/operatingModes/{mode_id}"
95
+ params = {}
96
+ org_id = get_org_id()
97
+ if org_id is not None:
98
+ params["orgId"] = org_id
99
+ if json_body:
100
+ body = json.loads(json_body)
101
+ else:
102
+ body = {}
103
+ if name is not None:
104
+ body["name"] = name
105
+ try:
106
+ result = api.session.rest_put(url, json=body, params=params)
107
+ except WebexError as e:
108
+ handle_rest_error(e)
109
+ typer.echo(f"Updated.")
110
+
111
+
112
+
113
+ @app.command("delete")
114
+ def delete(
115
+ mode_id: str = typer.Argument(help="modeId"),
116
+ force: bool = typer.Option(False, "--force", help="Skip confirmation"),
117
+ debug: bool = typer.Option(False, "--debug"),
118
+ ):
119
+ """Delete an Operating Mode."""
120
+ if not force:
121
+ typer.confirm(f"Delete {mode_id}?", abort=True)
122
+ api = get_api(debug=debug)
123
+ url = f"https://webexapis.com/v1/telephony/config/operatingModes/{mode_id}"
124
+ params = {}
125
+ org_id = get_org_id()
126
+ if org_id is not None:
127
+ params["orgId"] = org_id
128
+ try:
129
+ api.session.rest_delete(url, params=params)
130
+ except WebexError as e:
131
+ handle_rest_error(e)
132
+ typer.echo(f"Deleted: {mode_id}")
133
+
134
+
135
+
136
+ @app.command("create")
137
+ def create(
138
+ name: str = typer.Option(None, "--name", help="(required) Unique name for the `operating mode`."),
139
+ type_param: str = typer.Option(None, "--type", help="(required) Choices: SAME_HOURS_DAILY, DIFFERENT_HOURS_DAILY, HOLIDAY, NONE"),
140
+ level: str = typer.Option(None, "--level", help="(required) Choices: ORGANIZATION, LOCATION"),
141
+ location_id: str = typer.Option(None, "--location-id", help="Unique identifier of the location. Mandatory if level is `LO"),
142
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
143
+ output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
144
+ debug: bool = typer.Option(False, "--debug"),
145
+ ):
146
+ """Create an Operating Mode\n\nExample --json-body:\n '{"name":"...","type":"SAME_HOURS_DAILY","level":"ORGANIZATION","callForwarding":{"enabled":true,"destination":"...","destinationVoicemailEnabled":true},"locationId":"...","sameHoursDaily":{"mondayToFriday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."},"saturdayToSunday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."}},"differentHoursDaily":{"sunday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."},"monday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."},"tuesday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."},"wednesday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."},"thursday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."},"friday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."},"saturday":{"enabled":"...","allDayEnabled":"...","startTime":"...","endTime":"..."}},"holidays":[{"name":"...","allDayEnabled":"...","startDate":"...","endDate":"...","startTime":"...","endTime":"...","recurrence":"..."}]}'."""
147
+ api = get_api(debug=debug)
148
+ url = f"https://webexapis.com/v1/telephony/config/operatingModes/"
149
+ params = {}
150
+ org_id = get_org_id()
151
+ if org_id is not None:
152
+ params["orgId"] = org_id
153
+ if json_body:
154
+ body = json.loads(json_body)
155
+ else:
156
+ body = {}
157
+ if name is not None:
158
+ body["name"] = name
159
+ if type_param is not None:
160
+ body["type"] = type_param
161
+ if level is not None:
162
+ body["level"] = level
163
+ if location_id is not None:
164
+ body["locationId"] = location_id
165
+ _missing = [f for f in ['name', 'type', 'level'] if f not in body or body[f] is None]
166
+ if _missing:
167
+ typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
168
+ raise typer.Exit(1)
169
+ try:
170
+ result = api.session.rest_post(url, json=body, params=params)
171
+ except WebexError as e:
172
+ handle_rest_error(e)
173
+ if output == "json":
174
+ print_json(result)
175
+ elif isinstance(result, dict) and "id" in result:
176
+ typer.echo(f"Created: {result['id']}")
177
+ elif not result or result == {}:
178
+ typer.echo("Created.")
179
+ else:
180
+ print_json(result)
181
+
182
+
183
+
184
+ @app.command("show-holidays")
185
+ def show_holidays(
186
+ mode_id: str = typer.Argument(help="modeId"),
187
+ holiday_id: str = typer.Argument(help="holidayId"),
188
+ output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
189
+ debug: bool = typer.Option(False, "--debug"),
190
+ ):
191
+ """Get details for an Operating Mode Holiday."""
192
+ api = get_api(debug=debug)
193
+ url = f"https://webexapis.com/v1/telephony/config/operatingModes/{mode_id}/holidays/{holiday_id}"
194
+ params = {}
195
+ org_id = get_org_id()
196
+ if org_id is not None:
197
+ params["orgId"] = org_id
198
+ try:
199
+ result = api.session.rest_get(url, params=params)
200
+ except WebexError as e:
201
+ handle_rest_error(e)
202
+ if output == "json":
203
+ print_json(result)
204
+ else:
205
+ if isinstance(result, dict):
206
+ print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
207
+ elif isinstance(result, list):
208
+ print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
209
+ else:
210
+ print_json(result)
211
+
212
+
213
+
214
+ @app.command("update-holidays")
215
+ def update_holidays(
216
+ mode_id: str = typer.Argument(help="modeId"),
217
+ holiday_id: str = typer.Argument(help="holidayId"),
218
+ name: str = typer.Option(None, "--name", help="Name of the holiday."),
219
+ all_day_enabled: bool = typer.Option(None, "--all-day-enabled/--no-all-day-enabled", help="Specifies if the `operating mode holiday` schedule event is"),
220
+ start_date: str = typer.Option(None, "--start-date", help="Start date of the `operating mode holiday`."),
221
+ end_date: str = typer.Option(None, "--end-date", help="End date of the `operating mode holiday`."),
222
+ start_time: str = typer.Option(None, "--start-time", help="Start time for the `operating mode holiday`. Mandatory if `a"),
223
+ end_time: str = typer.Option(None, "--end-time", help="End time for the `operating mode holiday`. Mandatory if `all"),
224
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
225
+ debug: bool = typer.Option(False, "--debug"),
226
+ ):
227
+ """Modify an Operating Mode Holiday\n\nExample --json-body:\n '{"name":"...","allDayEnabled":true,"startDate":"...","endDate":"...","startTime":"...","endTime":"...","recurrence":{"recurYearlyByDate":{"dayOfMonth":"...","month":"..."},"recurYearlyByDay":{"day":"...","week":"...","month":"..."}}}'."""
228
+ api = get_api(debug=debug)
229
+ url = f"https://webexapis.com/v1/telephony/config/operatingModes/{mode_id}/holidays/{holiday_id}"
230
+ params = {}
231
+ org_id = get_org_id()
232
+ if org_id is not None:
233
+ params["orgId"] = org_id
234
+ if json_body:
235
+ body = json.loads(json_body)
236
+ else:
237
+ body = {}
238
+ if name is not None:
239
+ body["name"] = name
240
+ if all_day_enabled is not None:
241
+ body["allDayEnabled"] = all_day_enabled
242
+ if start_date is not None:
243
+ body["startDate"] = start_date
244
+ if end_date is not None:
245
+ body["endDate"] = end_date
246
+ if start_time is not None:
247
+ body["startTime"] = start_time
248
+ if end_time is not None:
249
+ body["endTime"] = end_time
250
+ try:
251
+ result = api.session.rest_put(url, json=body, params=params)
252
+ except WebexError as e:
253
+ handle_rest_error(e)
254
+ typer.echo(f"Updated.")
255
+
256
+
257
+
258
+ @app.command("delete-holidays")
259
+ def delete_holidays(
260
+ mode_id: str = typer.Argument(help="modeId"),
261
+ holiday_id: str = typer.Argument(help="holidayId"),
262
+ force: bool = typer.Option(False, "--force", help="Skip confirmation"),
263
+ debug: bool = typer.Option(False, "--debug"),
264
+ ):
265
+ """Delete an Operating Mode Holiday."""
266
+ if not force:
267
+ typer.confirm(f"Delete {holiday_id}?", abort=True)
268
+ api = get_api(debug=debug)
269
+ url = f"https://webexapis.com/v1/telephony/config/operatingModes/{mode_id}/holidays/{holiday_id}"
270
+ params = {}
271
+ org_id = get_org_id()
272
+ if org_id is not None:
273
+ params["orgId"] = org_id
274
+ try:
275
+ api.session.rest_delete(url, params=params)
276
+ except WebexError as e:
277
+ handle_rest_error(e)
278
+ typer.echo(f"Deleted: {holiday_id}")
279
+
280
+
281
+
282
+ @app.command("create-holidays")
283
+ def create_holidays(
284
+ mode_id: str = typer.Argument(help="modeId"),
285
+ name: str = typer.Option(None, "--name", help="(required) Name of the holiday."),
286
+ all_day_enabled: bool = typer.Option(None, "--all-day-enabled/--no-all-day-enabled", help="(required) Specifies if the `operating mode holiday` schedule event is"),
287
+ start_date: str = typer.Option(None, "--start-date", help="(required) Start date of the `operating mode holiday`."),
288
+ end_date: str = typer.Option(None, "--end-date", help="(required) End date of the `operating mode holiday`."),
289
+ start_time: str = typer.Option(None, "--start-time", help="Start time for the `operating mode holiday`. Mandatory if `a"),
290
+ end_time: str = typer.Option(None, "--end-time", help="End time for the `operating mode holiday`. Mandatory if `all"),
291
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
292
+ output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
293
+ debug: bool = typer.Option(False, "--debug"),
294
+ ):
295
+ """Create an Operating Mode Holiday\n\nExample --json-body:\n '{"name":"...","allDayEnabled":true,"startDate":"...","endDate":"...","startTime":"...","endTime":"...","recurrence":{"recurYearlyByDate":{"dayOfMonth":"...","month":"..."},"recurYearlyByDay":{"day":"...","week":"...","month":"..."}}}'."""
296
+ api = get_api(debug=debug)
297
+ url = f"https://webexapis.com/v1/telephony/config/operatingModes/{mode_id}/holidays"
298
+ params = {}
299
+ org_id = get_org_id()
300
+ if org_id is not None:
301
+ params["orgId"] = org_id
302
+ if json_body:
303
+ body = json.loads(json_body)
304
+ else:
305
+ body = {}
306
+ if name is not None:
307
+ body["name"] = name
308
+ if all_day_enabled is not None:
309
+ body["allDayEnabled"] = all_day_enabled
310
+ if start_date is not None:
311
+ body["startDate"] = start_date
312
+ if end_date is not None:
313
+ body["endDate"] = end_date
314
+ if start_time is not None:
315
+ body["startTime"] = start_time
316
+ if end_time is not None:
317
+ body["endTime"] = end_time
318
+ _missing = [f for f in ['name', 'allDayEnabled', 'startDate', 'endDate'] if f not in body or body[f] is None]
319
+ if _missing:
320
+ typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
321
+ raise typer.Exit(1)
322
+ try:
323
+ result = api.session.rest_post(url, json=body, params=params)
324
+ except WebexError as e:
325
+ handle_rest_error(e)
326
+ if output == "json":
327
+ print_json(result)
328
+ elif isinstance(result, dict) and "id" in result:
329
+ typer.echo(f"Created: {result['id']}")
330
+ elif not result or result == {}:
331
+ typer.echo("Created.")
332
+ else:
333
+ print_json(result)
334
+
335
+
336
+
337
+ @app.command("list-available-operating-modes")
338
+ def list_available_operating_modes(
339
+ location_id: str = typer.Argument(help="locationId"),
340
+ output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
341
+ limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
342
+ offset: int = typer.Option(0, "--offset", help="Start offset"),
343
+ debug: bool = typer.Option(False, "--debug"),
344
+ ):
345
+ """Retrieve the List of Available Operating Modes in a Location."""
346
+ api = get_api(debug=debug)
347
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/operatingModes/availableOperatingModes"
348
+ params = {}
349
+ if limit > 0:
350
+ params["max"] = limit
351
+ if offset > 0:
352
+ params["start"] = offset
353
+ org_id = get_org_id()
354
+ if org_id is not None:
355
+ params["orgId"] = org_id
356
+ result = None
357
+ try:
358
+ result = api.session.rest_get(url, params=params)
359
+ except WebexError as e:
360
+ handle_rest_error(e)
361
+ result = result or []
362
+ items = result.get("operatingModes", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
363
+ if output == "json":
364
+ print_json(items)
365
+ else:
366
+ print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
367
+
368
+
369
+
370
+ @app.command("list-available-numbers")
371
+ def list_available_numbers(
372
+ location_id: str = typer.Argument(help="locationId"),
373
+ phone_number: str = typer.Option(None, "--phone-number", help="Filter phone numbers based on the comma-separated list provi"),
374
+ owner_name: str = typer.Option(None, "--owner-name", help="Return the list of phone numbers that are owned by the given"),
375
+ extension: str = typer.Option(None, "--extension", help="Returns the list of PSTN phone numbers with the given `exten"),
376
+ output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
377
+ limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
378
+ offset: int = typer.Option(0, "--offset", help="Start offset"),
379
+ debug: bool = typer.Option(False, "--debug"),
380
+ ):
381
+ """Get Operating Mode Call Forward Available Phone Numbers."""
382
+ api = get_api(debug=debug)
383
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/operatingModes/callForwarding/availableNumbers"
384
+ params = {}
385
+ if phone_number is not None:
386
+ params["phoneNumber"] = phone_number
387
+ if owner_name is not None:
388
+ params["ownerName"] = owner_name
389
+ if extension is not None:
390
+ params["extension"] = extension
391
+ if limit > 0:
392
+ params["max"] = limit
393
+ if offset > 0:
394
+ params["start"] = offset
395
+ org_id = get_org_id()
396
+ if org_id is not None:
397
+ params["orgId"] = org_id
398
+ result = None
399
+ try:
400
+ result = api.session.rest_get(url, params=params)
401
+ except WebexError as e:
402
+ handle_rest_error(e)
403
+ result = result or []
404
+ items = result.get("phoneNumbers", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
405
+ if output == "json":
406
+ print_json(items)
407
+ else:
408
+ print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
409
+
410
+