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,577 @@
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 location-call-handling.")
10
+
11
+
12
+ @app.command("generate-example-password")
13
+ def generate_example_password(
14
+ location_id: str = typer.Argument(help="locationId"),
15
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body"),
16
+ debug: bool = typer.Option(False, "--debug"),
17
+ ):
18
+ """Generate example password for Location\n\nExample --json-body:\n '{"generate":["sip"]}'."""
19
+ api = get_api(debug=debug)
20
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/actions/generatePassword/invoke"
21
+ params = {}
22
+ org_id = get_org_id()
23
+ if org_id is not None:
24
+ params["orgId"] = org_id
25
+ if json_body:
26
+ body = json.loads(json_body)
27
+ else:
28
+ body = {}
29
+ try:
30
+ result = api.session.rest_post(url, json=body, params=params)
31
+ except WebexError as e:
32
+ handle_rest_error(e)
33
+ print_json(result)
34
+
35
+
36
+
37
+ @app.command("show")
38
+ def show(
39
+ location_id: str = typer.Argument(help="locationId"),
40
+ output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
41
+ debug: bool = typer.Option(False, "--debug"),
42
+ ):
43
+ """Read the Internal Dialing configuration for a location."""
44
+ api = get_api(debug=debug)
45
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/internalDialing"
46
+ params = {}
47
+ org_id = get_org_id()
48
+ if org_id is not None:
49
+ params["orgId"] = org_id
50
+ try:
51
+ result = api.session.rest_get(url, params=params)
52
+ except WebexError as e:
53
+ handle_rest_error(e)
54
+ if output == "json":
55
+ print_json(result)
56
+ else:
57
+ if isinstance(result, dict):
58
+ print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
59
+ elif isinstance(result, list):
60
+ print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
61
+ else:
62
+ print_json(result)
63
+
64
+
65
+
66
+ @app.command("update")
67
+ def update(
68
+ location_id: str = typer.Argument(help="locationId"),
69
+ enable_unknown_extension_route_policy: bool = typer.Option(None, "--enable-unknown-extension-route-policy/--no-enable-unknown-extension-route-policy", help="When enabled, calls made by users at the location to an unkn"),
70
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
71
+ debug: bool = typer.Option(False, "--debug"),
72
+ ):
73
+ """Modify the Internal Dialing configuration for a location\n\nExample --json-body:\n '{"enableUnknownExtensionRoutePolicy":true,"unknownExtensionRouteIdentity":{"id":"...","type":"ROUTE_GROUP"}}'."""
74
+ api = get_api(debug=debug)
75
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/internalDialing"
76
+ params = {}
77
+ org_id = get_org_id()
78
+ if org_id is not None:
79
+ params["orgId"] = org_id
80
+ if json_body:
81
+ body = json.loads(json_body)
82
+ else:
83
+ body = {}
84
+ if enable_unknown_extension_route_policy is not None:
85
+ body["enableUnknownExtensionRoutePolicy"] = enable_unknown_extension_route_policy
86
+ try:
87
+ result = api.session.rest_put(url, json=body, params=params)
88
+ except WebexError as e:
89
+ handle_rest_error(e)
90
+ typer.echo(f"Updated.")
91
+
92
+
93
+
94
+ @app.command("show-intercept")
95
+ def show_intercept(
96
+ location_id: str = typer.Argument(help="locationId"),
97
+ output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
98
+ debug: bool = typer.Option(False, "--debug"),
99
+ ):
100
+ """Get Location Intercept."""
101
+ api = get_api(debug=debug)
102
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/intercept"
103
+ params = {}
104
+ org_id = get_org_id()
105
+ if org_id is not None:
106
+ params["orgId"] = org_id
107
+ try:
108
+ result = api.session.rest_get(url, params=params)
109
+ except WebexError as e:
110
+ handle_rest_error(e)
111
+ if output == "json":
112
+ print_json(result)
113
+ else:
114
+ if isinstance(result, dict):
115
+ print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
116
+ elif isinstance(result, list):
117
+ print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
118
+ else:
119
+ print_json(result)
120
+
121
+
122
+
123
+ @app.command("update-intercept")
124
+ def update_intercept(
125
+ location_id: str = typer.Argument(help="locationId"),
126
+ enabled: bool = typer.Option(None, "--enabled/--no-enabled", help="Enable/disable location intercept. Enable this feature to ov"),
127
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
128
+ debug: bool = typer.Option(False, "--debug"),
129
+ ):
130
+ """Put Location Intercept\n\nExample --json-body:\n '{"enabled":true,"incoming":{"type":"INTERCEPT_ALL","voicemailEnabled":true,"announcements":{"greeting":"...","fileName":"...","newNumber":"...","zeroTransfer":"..."}},"outgoing":{"type":"INTERCEPT_ALL","transferEnabled":true,"destination":"..."}}'."""
131
+ api = get_api(debug=debug)
132
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/intercept"
133
+ params = {}
134
+ org_id = get_org_id()
135
+ if org_id is not None:
136
+ params["orgId"] = org_id
137
+ if json_body:
138
+ body = json.loads(json_body)
139
+ else:
140
+ body = {}
141
+ if enabled is not None:
142
+ body["enabled"] = enabled
143
+ try:
144
+ result = api.session.rest_put(url, json=body, params=params)
145
+ except WebexError as e:
146
+ handle_rest_error(e)
147
+ typer.echo(f"Updated.")
148
+
149
+
150
+
151
+ @app.command("list")
152
+ def cmd_list(
153
+ location_id: str = typer.Argument(help="locationId"),
154
+ output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
155
+ limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
156
+ offset: int = typer.Option(0, "--offset", help="Start offset"),
157
+ debug: bool = typer.Option(False, "--debug"),
158
+ ):
159
+ """Get Location Outgoing Permission."""
160
+ api = get_api(debug=debug)
161
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/outgoingPermission"
162
+ params = {}
163
+ if limit > 0:
164
+ params["max"] = limit
165
+ if offset > 0:
166
+ params["start"] = offset
167
+ org_id = get_org_id()
168
+ if org_id is not None:
169
+ params["orgId"] = org_id
170
+ result = None
171
+ try:
172
+ result = api.session.rest_get(url, params=params)
173
+ except WebexError as e:
174
+ handle_rest_error(e)
175
+ result = result or []
176
+ items = result.get("callingPermissions", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
177
+ if output == "json":
178
+ print_json(items)
179
+ else:
180
+ print_table(items, columns=[('Call Type', 'callType'), ('Action', 'action'), ('Transfer', 'transferEnabled')], limit=limit)
181
+
182
+
183
+
184
+ @app.command("update-outgoing-permission")
185
+ def update_outgoing_permission(
186
+ location_id: str = typer.Argument(help="locationId"),
187
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
188
+ debug: bool = typer.Option(False, "--debug"),
189
+ ):
190
+ """Update Location Outgoing Permission\n\nExample --json-body:\n '{"callingPermissions":[{"callType":"...","action":"...","transferEnabled":"..."}]}'."""
191
+ api = get_api(debug=debug)
192
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/outgoingPermission"
193
+ params = {}
194
+ org_id = get_org_id()
195
+ if org_id is not None:
196
+ params["orgId"] = org_id
197
+ if json_body:
198
+ body = json.loads(json_body)
199
+ else:
200
+ body = {}
201
+ try:
202
+ result = api.session.rest_put(url, json=body, params=params)
203
+ except WebexError as e:
204
+ handle_rest_error(e)
205
+ typer.echo(f"Updated.")
206
+
207
+
208
+
209
+ @app.command("show-auto-transfer-numbers")
210
+ def show_auto_transfer_numbers(
211
+ location_id: str = typer.Argument(help="locationId"),
212
+ output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
213
+ debug: bool = typer.Option(False, "--debug"),
214
+ ):
215
+ """Get Outgoing Permission Auto Transfer Number."""
216
+ api = get_api(debug=debug)
217
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/outgoingPermission/autoTransferNumbers"
218
+ params = {}
219
+ org_id = get_org_id()
220
+ if org_id is not None:
221
+ params["orgId"] = org_id
222
+ try:
223
+ result = api.session.rest_get(url, params=params)
224
+ except WebexError as e:
225
+ handle_rest_error(e)
226
+ if output == "json":
227
+ print_json(result)
228
+ else:
229
+ if isinstance(result, dict):
230
+ print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
231
+ elif isinstance(result, list):
232
+ print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
233
+ else:
234
+ print_json(result)
235
+
236
+
237
+
238
+ @app.command("update-auto-transfer-numbers")
239
+ def update_auto_transfer_numbers(
240
+ location_id: str = typer.Argument(help="locationId"),
241
+ auto_transfer_number1: str = typer.Option(None, "--auto-transfer-number1", help="Calls placed meeting the criteria in an outbound rule whose"),
242
+ auto_transfer_number2: str = typer.Option(None, "--auto-transfer-number2", help="Calls placed meeting the criteria in an outbound rule whose"),
243
+ auto_transfer_number3: str = typer.Option(None, "--auto-transfer-number3", help="Calls placed meeting the criteria in an outbound rule whose"),
244
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
245
+ debug: bool = typer.Option(False, "--debug"),
246
+ ):
247
+ """Put Outgoing Permission Auto Transfer Number."""
248
+ api = get_api(debug=debug)
249
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/outgoingPermission/autoTransferNumbers"
250
+ params = {}
251
+ org_id = get_org_id()
252
+ if org_id is not None:
253
+ params["orgId"] = org_id
254
+ if json_body:
255
+ body = json.loads(json_body)
256
+ else:
257
+ body = {}
258
+ if auto_transfer_number1 is not None:
259
+ body["autoTransferNumber1"] = auto_transfer_number1
260
+ if auto_transfer_number2 is not None:
261
+ body["autoTransferNumber2"] = auto_transfer_number2
262
+ if auto_transfer_number3 is not None:
263
+ body["autoTransferNumber3"] = auto_transfer_number3
264
+ try:
265
+ result = api.session.rest_put(url, json=body, params=params)
266
+ except WebexError as e:
267
+ handle_rest_error(e)
268
+ typer.echo(f"Updated.")
269
+
270
+
271
+
272
+ @app.command("show-access-codes")
273
+ def show_access_codes(
274
+ location_id: str = typer.Argument(help="locationId"),
275
+ output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
276
+ debug: bool = typer.Option(False, "--debug"),
277
+ ):
278
+ """Get Outgoing Permission Location Access Code."""
279
+ api = get_api(debug=debug)
280
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/outgoingPermission/accessCodes"
281
+ params = {}
282
+ org_id = get_org_id()
283
+ if org_id is not None:
284
+ params["orgId"] = org_id
285
+ try:
286
+ result = api.session.rest_get(url, params=params)
287
+ except WebexError as e:
288
+ handle_rest_error(e)
289
+ if output == "json":
290
+ print_json(result)
291
+ else:
292
+ if isinstance(result, dict):
293
+ print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
294
+ elif isinstance(result, list):
295
+ print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
296
+ else:
297
+ print_json(result)
298
+
299
+
300
+
301
+ @app.command("create")
302
+ def create(
303
+ location_id: str = typer.Argument(help="locationId"),
304
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
305
+ output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
306
+ debug: bool = typer.Option(False, "--debug"),
307
+ ):
308
+ """Create Outgoing Permission a new access code for a customer location\n\nExample --json-body:\n '{"accessCodes":{"code":"...","description":"..."}}'."""
309
+ api = get_api(debug=debug)
310
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/outgoingPermission/accessCodes"
311
+ params = {}
312
+ org_id = get_org_id()
313
+ if org_id is not None:
314
+ params["orgId"] = org_id
315
+ if json_body:
316
+ body = json.loads(json_body)
317
+ else:
318
+ body = {}
319
+ try:
320
+ result = api.session.rest_post(url, json=body, params=params)
321
+ except WebexError as e:
322
+ handle_rest_error(e)
323
+ if output == "json":
324
+ print_json(result)
325
+ elif isinstance(result, dict) and "id" in result:
326
+ typer.echo(f"Created: {result['id']}")
327
+ elif not result or result == {}:
328
+ typer.echo("Created.")
329
+ else:
330
+ print_json(result)
331
+
332
+
333
+
334
+ @app.command("update-access-codes")
335
+ def update_access_codes(
336
+ location_id: str = typer.Argument(help="locationId"),
337
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
338
+ debug: bool = typer.Option(False, "--debug"),
339
+ ):
340
+ """Delete Outgoing Permission Access Code Location\n\nExample --json-body:\n '{"deleteCodes":["..."]}'."""
341
+ api = get_api(debug=debug)
342
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/outgoingPermission/accessCodes"
343
+ params = {}
344
+ org_id = get_org_id()
345
+ if org_id is not None:
346
+ params["orgId"] = org_id
347
+ if json_body:
348
+ body = json.loads(json_body)
349
+ else:
350
+ body = {}
351
+ try:
352
+ result = api.session.rest_put(url, json=body, params=params)
353
+ except WebexError as e:
354
+ handle_rest_error(e)
355
+ typer.echo(f"Updated.")
356
+
357
+
358
+
359
+ @app.command("delete")
360
+ def delete(
361
+ location_id: str = typer.Argument(help="locationId"),
362
+ force: bool = typer.Option(False, "--force", help="Skip confirmation"),
363
+ debug: bool = typer.Option(False, "--debug"),
364
+ ):
365
+ """Delete all Outgoing Permission Access Code for a Location."""
366
+ if not force:
367
+ typer.confirm(f"Delete {location_id}?", abort=True)
368
+ api = get_api(debug=debug)
369
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/outgoingPermission/accessCodes"
370
+ params = {}
371
+ org_id = get_org_id()
372
+ if org_id is not None:
373
+ params["orgId"] = org_id
374
+ try:
375
+ api.session.rest_delete(url, params=params)
376
+ except WebexError as e:
377
+ handle_rest_error(e)
378
+ typer.echo(f"Deleted: {location_id}")
379
+
380
+
381
+
382
+ @app.command("list-digit-patterns")
383
+ def list_digit_patterns(
384
+ location_id: str = typer.Argument(help="locationId"),
385
+ output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
386
+ limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
387
+ offset: int = typer.Option(0, "--offset", help="Start offset"),
388
+ debug: bool = typer.Option(False, "--debug"),
389
+ ):
390
+ """Get Outgoing Permission Digit Pattern for a Location."""
391
+ api = get_api(debug=debug)
392
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/outgoingPermission/digitPatterns"
393
+ params = {}
394
+ if limit > 0:
395
+ params["max"] = limit
396
+ if offset > 0:
397
+ params["start"] = offset
398
+ org_id = get_org_id()
399
+ if org_id is not None:
400
+ params["orgId"] = org_id
401
+ result = None
402
+ try:
403
+ result = api.session.rest_get(url, params=params)
404
+ except WebexError as e:
405
+ handle_rest_error(e)
406
+ result = result or []
407
+ items = result.get("digitPatterns", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
408
+ if output == "json":
409
+ print_json(items)
410
+ else:
411
+ print_table(items, columns=[('ID', 'id'), ('Name', 'name'), ('Pattern', 'pattern'), ('Action', 'action')], limit=limit)
412
+
413
+
414
+
415
+ @app.command("create-digit-patterns")
416
+ def create_digit_patterns(
417
+ location_id: str = typer.Argument(help="locationId"),
418
+ name: str = typer.Option(None, "--name", help="(required) A unique name for the digit pattern."),
419
+ pattern: str = typer.Option(None, "--pattern", help="(required) The digit pattern to be matched with the input number."),
420
+ action: str = typer.Option(None, "--action", help="(required) Choices: ALLOW, BLOCK, AUTH_CODE, TRANSFER_NUMBER_1, TRANSFER_NUMBER_2, TRANSFER_NUMBER_3"),
421
+ transfer_enabled: bool = typer.Option(None, "--transfer-enabled/--no-transfer-enabled", help="(required) If `true`, allows transfer and forwarding for the call type."),
422
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
423
+ output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
424
+ debug: bool = typer.Option(False, "--debug"),
425
+ ):
426
+ """Create Outgoing Permission a new Digit Pattern for a location."""
427
+ api = get_api(debug=debug)
428
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/outgoingPermission/digitPatterns"
429
+ params = {}
430
+ org_id = get_org_id()
431
+ if org_id is not None:
432
+ params["orgId"] = org_id
433
+ if json_body:
434
+ body = json.loads(json_body)
435
+ else:
436
+ body = {}
437
+ if name is not None:
438
+ body["name"] = name
439
+ if pattern is not None:
440
+ body["pattern"] = pattern
441
+ if action is not None:
442
+ body["action"] = action
443
+ if transfer_enabled is not None:
444
+ body["transferEnabled"] = transfer_enabled
445
+ _missing = [f for f in ['name', 'pattern', 'action', 'transferEnabled'] if f not in body or body[f] is None]
446
+ if _missing:
447
+ typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
448
+ raise typer.Exit(1)
449
+ try:
450
+ result = api.session.rest_post(url, json=body, params=params)
451
+ except WebexError as e:
452
+ handle_rest_error(e)
453
+ if output == "json":
454
+ print_json(result)
455
+ elif isinstance(result, dict) and "id" in result:
456
+ typer.echo(f"Created: {result['id']}")
457
+ elif not result or result == {}:
458
+ typer.echo("Created.")
459
+ else:
460
+ print_json(result)
461
+
462
+
463
+
464
+ @app.command("delete-digit-patterns-outgoing-permission")
465
+ def delete_digit_patterns_outgoing_permission(
466
+ location_id: str = typer.Argument(help="locationId"),
467
+ force: bool = typer.Option(False, "--force", help="Skip confirmation"),
468
+ debug: bool = typer.Option(False, "--debug"),
469
+ ):
470
+ """Delete all Outgoing Permission Digit Patterns for a Location."""
471
+ if not force:
472
+ typer.confirm(f"Delete {location_id}?", abort=True)
473
+ api = get_api(debug=debug)
474
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/outgoingPermission/digitPatterns"
475
+ params = {}
476
+ org_id = get_org_id()
477
+ if org_id is not None:
478
+ params["orgId"] = org_id
479
+ try:
480
+ api.session.rest_delete(url, params=params)
481
+ except WebexError as e:
482
+ handle_rest_error(e)
483
+ typer.echo(f"Deleted: {location_id}")
484
+
485
+
486
+
487
+ @app.command("show-digit-patterns")
488
+ def show_digit_patterns(
489
+ location_id: str = typer.Argument(help="locationId"),
490
+ digit_pattern_id: str = typer.Argument(help="digitPatternId"),
491
+ output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
492
+ debug: bool = typer.Option(False, "--debug"),
493
+ ):
494
+ """Get Details for a Outgoing Permission Digit Pattern for a Location."""
495
+ api = get_api(debug=debug)
496
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/outgoingPermission/digitPatterns/{digit_pattern_id}"
497
+ params = {}
498
+ org_id = get_org_id()
499
+ if org_id is not None:
500
+ params["orgId"] = org_id
501
+ try:
502
+ result = api.session.rest_get(url, params=params)
503
+ except WebexError as e:
504
+ handle_rest_error(e)
505
+ if output == "json":
506
+ print_json(result)
507
+ else:
508
+ if isinstance(result, dict):
509
+ print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
510
+ elif isinstance(result, list):
511
+ print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
512
+ else:
513
+ print_json(result)
514
+
515
+
516
+
517
+ @app.command("update-digit-patterns")
518
+ def update_digit_patterns(
519
+ location_id: str = typer.Argument(help="locationId"),
520
+ digit_pattern_id: str = typer.Argument(help="digitPatternId"),
521
+ name: str = typer.Option(None, "--name", help="A unique name for the digit pattern."),
522
+ pattern: str = typer.Option(None, "--pattern", help="The digit pattern to be matched with the input number."),
523
+ action: str = typer.Option(None, "--action", help="Choices: ALLOW, BLOCK, AUTH_CODE, TRANSFER_NUMBER_1, TRANSFER_NUMBER_2, TRANSFER_NUMBER_3"),
524
+ transfer_enabled: bool = typer.Option(None, "--transfer-enabled/--no-transfer-enabled", help="If `true`, allows transfer and forwarding for the call type."),
525
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
526
+ debug: bool = typer.Option(False, "--debug"),
527
+ ):
528
+ """Update a Outgoing Permission Digit Pattern for a Location."""
529
+ api = get_api(debug=debug)
530
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/outgoingPermission/digitPatterns/{digit_pattern_id}"
531
+ params = {}
532
+ org_id = get_org_id()
533
+ if org_id is not None:
534
+ params["orgId"] = org_id
535
+ if json_body:
536
+ body = json.loads(json_body)
537
+ else:
538
+ body = {}
539
+ if name is not None:
540
+ body["name"] = name
541
+ if pattern is not None:
542
+ body["pattern"] = pattern
543
+ if action is not None:
544
+ body["action"] = action
545
+ if transfer_enabled is not None:
546
+ body["transferEnabled"] = transfer_enabled
547
+ try:
548
+ result = api.session.rest_put(url, json=body, params=params)
549
+ except WebexError as e:
550
+ handle_rest_error(e)
551
+ typer.echo(f"Updated.")
552
+
553
+
554
+
555
+ @app.command("delete-digit-patterns-outgoing-permission-1")
556
+ def delete_digit_patterns_outgoing_permission_1(
557
+ location_id: str = typer.Argument(help="locationId"),
558
+ digit_pattern_id: str = typer.Argument(help="digitPatternId"),
559
+ force: bool = typer.Option(False, "--force", help="Skip confirmation"),
560
+ debug: bool = typer.Option(False, "--debug"),
561
+ ):
562
+ """Delete a Outgoing Permission Digit Pattern for a Location."""
563
+ if not force:
564
+ typer.confirm(f"Delete {digit_pattern_id}?", abort=True)
565
+ api = get_api(debug=debug)
566
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/outgoingPermission/digitPatterns/{digit_pattern_id}"
567
+ params = {}
568
+ org_id = get_org_id()
569
+ if org_id is not None:
570
+ params["orgId"] = org_id
571
+ try:
572
+ api.session.rest_delete(url, params=params)
573
+ except WebexError as e:
574
+ handle_rest_error(e)
575
+ typer.echo(f"Deleted: {digit_pattern_id}")
576
+
577
+