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.
- wxcli/__init__.py +4 -0
- wxcli/_playbook/.claude/agents/migration-advisor.md +239 -0
- wxcli/_playbook/.claude/agents/wxc-calling-builder.md +946 -0
- wxcli/_playbook/.claude/rules/cleanup.md +29 -0
- wxcli/_playbook/.claude/rules/cucm-migration.md +58 -0
- wxcli/_playbook/.claude/rules/org-health.md +14 -0
- wxcli/_playbook/.claude/settings.json +8 -0
- wxcli/_playbook/.claude/skills/audit-compliance/SKILL.md +515 -0
- wxcli/_playbook/.claude/skills/call-control/SKILL.md +747 -0
- wxcli/_playbook/.claude/skills/configure-features/SKILL.md +623 -0
- wxcli/_playbook/.claude/skills/configure-routing/SKILL.md +627 -0
- wxcli/_playbook/.claude/skills/contact-center/SKILL.md +1181 -0
- wxcli/_playbook/.claude/skills/cucm-migrate/SKILL.md +820 -0
- wxcli/_playbook/.claude/skills/customer-assist/SKILL.md +443 -0
- wxcli/_playbook/.claude/skills/device-platform/SKILL.md +407 -0
- wxcli/_playbook/.claude/skills/manage-call-settings/SKILL.md +757 -0
- wxcli/_playbook/.claude/skills/manage-devices/SKILL.md +790 -0
- wxcli/_playbook/.claude/skills/manage-identity/SKILL.md +638 -0
- wxcli/_playbook/.claude/skills/manage-licensing/SKILL.md +528 -0
- wxcli/_playbook/.claude/skills/manage-meetings/SKILL.md +708 -0
- wxcli/_playbook/.claude/skills/messaging-bots/SKILL.md +365 -0
- wxcli/_playbook/.claude/skills/messaging-spaces/SKILL.md +520 -0
- wxcli/_playbook/.claude/skills/org-health/SKILL.md +159 -0
- wxcli/_playbook/.claude/skills/provision-calling/SKILL.md +421 -0
- wxcli/_playbook/.claude/skills/query-live/SKILL.md +183 -0
- wxcli/_playbook/.claude/skills/query-live/domains/call-flow-trace.md +223 -0
- wxcli/_playbook/.claude/skills/query-live/domains/call-history.md +44 -0
- wxcli/_playbook/.claude/skills/query-live/domains/features.md +169 -0
- wxcli/_playbook/.claude/skills/query-live/domains/numbers.md +93 -0
- wxcli/_playbook/.claude/skills/query-live/domains/people-and-settings.md +146 -0
- wxcli/_playbook/.claude/skills/query-live/domains/routing.md +124 -0
- wxcli/_playbook/.claude/skills/reporting/SKILL.md +501 -0
- wxcli/_playbook/.claude/skills/reporting/references/cdr-recipes.md +1628 -0
- wxcli/_playbook/.claude/skills/reporting-cc/SKILL.md +251 -0
- wxcli/_playbook/.claude/skills/reporting-meetings/SKILL.md +290 -0
- wxcli/_playbook/.claude/skills/teardown/SKILL.md +214 -0
- wxcli/_playbook/.claude/skills/video-mesh/SKILL.md +379 -0
- wxcli/_playbook/.claude/skills/wxc-calling-debug/SKILL.md +475 -0
- wxcli/_playbook/CLAUDE.md +373 -0
- wxcli/_playbook/docs/reference/CLAUDE.md +25 -0
- wxcli/_playbook/docs/reference/admin-apps-data.md +643 -0
- wxcli/_playbook/docs/reference/admin-audit-security.md +322 -0
- wxcli/_playbook/docs/reference/admin-hybrid.md +383 -0
- wxcli/_playbook/docs/reference/admin-identity-scim.md +1007 -0
- wxcli/_playbook/docs/reference/admin-licensing.md +414 -0
- wxcli/_playbook/docs/reference/admin-org-management.md +586 -0
- wxcli/_playbook/docs/reference/admin-partner.md +357 -0
- wxcli/_playbook/docs/reference/archive/wxc-sdk-patterns.md +1229 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-advanced.md +835 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-core.md +743 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-devices-workspaces.md +1305 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-features.md +849 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-locations.md +938 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-person.md +1255 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-routing.md +1262 -0
- wxcli/_playbook/docs/reference/authentication.md +965 -0
- wxcli/_playbook/docs/reference/call-control.md +1205 -0
- wxcli/_playbook/docs/reference/call-features-additional.md +2541 -0
- wxcli/_playbook/docs/reference/call-features-major.md +1320 -0
- wxcli/_playbook/docs/reference/call-routing.md +2304 -0
- wxcli/_playbook/docs/reference/contact-center-analytics.md +1049 -0
- wxcli/_playbook/docs/reference/contact-center-core.md +1614 -0
- wxcli/_playbook/docs/reference/contact-center-journey.md +457 -0
- wxcli/_playbook/docs/reference/contact-center-routing.md +1138 -0
- wxcli/_playbook/docs/reference/devices-core.md +1869 -0
- wxcli/_playbook/docs/reference/devices-dect.md +1150 -0
- wxcli/_playbook/docs/reference/devices-platform.md +467 -0
- wxcli/_playbook/docs/reference/devices-workspaces.md +1426 -0
- wxcli/_playbook/docs/reference/emergency-services.md +1122 -0
- wxcli/_playbook/docs/reference/location-calling-core.md +2037 -0
- wxcli/_playbook/docs/reference/location-calling-media.md +1334 -0
- wxcli/_playbook/docs/reference/location-recording-advanced.md +1482 -0
- wxcli/_playbook/docs/reference/meetings-content.md +473 -0
- wxcli/_playbook/docs/reference/meetings-core.md +903 -0
- wxcli/_playbook/docs/reference/meetings-infrastructure.md +899 -0
- wxcli/_playbook/docs/reference/meetings-settings.md +850 -0
- wxcli/_playbook/docs/reference/messaging-bots.md +1091 -0
- wxcli/_playbook/docs/reference/messaging-spaces.md +695 -0
- wxcli/_playbook/docs/reference/person-call-settings-behavior.md +1639 -0
- wxcli/_playbook/docs/reference/person-call-settings-handling.md +1394 -0
- wxcli/_playbook/docs/reference/person-call-settings-media.md +1898 -0
- wxcli/_playbook/docs/reference/person-call-settings-permissions.md +1329 -0
- wxcli/_playbook/docs/reference/provisioning.md +1366 -0
- wxcli/_playbook/docs/reference/reporting-analytics.md +1318 -0
- wxcli/_playbook/docs/reference/self-service-call-settings.md +1020 -0
- wxcli/_playbook/docs/reference/virtual-lines.md +1132 -0
- wxcli/_playbook/docs/reference/webhooks-events.md +1444 -0
- wxcli/_playbook/docs/reference/wxcadm-xsi-realtime.md +953 -0
- wxcli/_version.py +24 -0
- wxcli/auth.py +137 -0
- wxcli/commands/__init__.py +0 -0
- wxcli/commands/_registry.py +181 -0
- wxcli/commands/activation_email.py +103 -0
- wxcli/commands/admin_recordings.py +585 -0
- wxcli/commands/analytics.py +105 -0
- wxcli/commands/announcement_playlists.py +219 -0
- wxcli/commands/announcements.py +519 -0
- wxcli/commands/archive_users.py +36 -0
- wxcli/commands/attachment_actions.py +60 -0
- wxcli/commands/audit_events.py +83 -0
- wxcli/commands/authorizations.py +113 -0
- wxcli/commands/auto_attendant.py +642 -0
- wxcli/commands/broadworks_billing_reports.py +126 -0
- wxcli/commands/broadworks_enterprises.py +160 -0
- wxcli/commands/broadworks_subscribers.py +319 -0
- wxcli/commands/broadworks_workspaces.py +108 -0
- wxcli/commands/call_controls.py +1304 -0
- wxcli/commands/call_park.py +494 -0
- wxcli/commands/call_pickup.py +229 -0
- wxcli/commands/call_queue.py +1878 -0
- wxcli/commands/call_recording.py +707 -0
- wxcli/commands/call_routing.py +1610 -0
- wxcli/commands/call_settings_for_me_phase_5.py +212 -0
- wxcli/commands/caller_reputation.py +169 -0
- wxcli/commands/calling_service.py +305 -0
- wxcli/commands/cc_address_book.py +770 -0
- wxcli/commands/cc_agent_greetings.py +242 -0
- wxcli/commands/cc_agent_summaries.py +39 -0
- wxcli/commands/cc_agent_wellbeing.py +216 -0
- wxcli/commands/cc_agents.py +425 -0
- wxcli/commands/cc_ai_assistant.py +55 -0
- wxcli/commands/cc_ai_feature.py +294 -0
- wxcli/commands/cc_audio_files.py +149 -0
- wxcli/commands/cc_auto_csat.py +311 -0
- wxcli/commands/cc_aux_code.py +458 -0
- wxcli/commands/cc_business_hour.py +353 -0
- wxcli/commands/cc_call_monitoring.py +228 -0
- wxcli/commands/cc_callbacks.py +194 -0
- wxcli/commands/cc_campaign.py +212 -0
- wxcli/commands/cc_captures.py +39 -0
- wxcli/commands/cc_contact_list.py +169 -0
- wxcli/commands/cc_contact_number.py +295 -0
- wxcli/commands/cc_data_sources.py +235 -0
- wxcli/commands/cc_desktop_layout.py +380 -0
- wxcli/commands/cc_desktop_profile.py +322 -0
- wxcli/commands/cc_dial_number.py +511 -0
- wxcli/commands/cc_dial_plan.py +347 -0
- wxcli/commands/cc_dnc.py +101 -0
- wxcli/commands/cc_entry_point.py +545 -0
- wxcli/commands/cc_ewt.py +51 -0
- wxcli/commands/cc_flow.py +477 -0
- wxcli/commands/cc_global_vars.py +430 -0
- wxcli/commands/cc_holiday_list.py +335 -0
- wxcli/commands/cc_journey.py +1261 -0
- wxcli/commands/cc_legacy_flows.py +49 -0
- wxcli/commands/cc_multimedia_profile.py +436 -0
- wxcli/commands/cc_notification.py +51 -0
- wxcli/commands/cc_outdial_ani.py +604 -0
- wxcli/commands/cc_overrides.py +341 -0
- wxcli/commands/cc_queue.py +1083 -0
- wxcli/commands/cc_queue_stats.py +55 -0
- wxcli/commands/cc_realtime.py +51 -0
- wxcli/commands/cc_resource_collection.py +312 -0
- wxcli/commands/cc_search.py +46 -0
- wxcli/commands/cc_site.py +400 -0
- wxcli/commands/cc_skill.py +350 -0
- wxcli/commands/cc_skill_profile.py +289 -0
- wxcli/commands/cc_subscriptions.py +426 -0
- wxcli/commands/cc_summaries.py +130 -0
- wxcli/commands/cc_tasks.py +844 -0
- wxcli/commands/cc_team.py +325 -0
- wxcli/commands/cc_user_profiles.py +349 -0
- wxcli/commands/cc_users.py +701 -0
- wxcli/commands/cc_work_types.py +363 -0
- wxcli/commands/cdr.py +89 -0
- wxcli/commands/classifications.py +38 -0
- wxcli/commands/cleanup.py +1427 -0
- wxcli/commands/client_settings.py +72 -0
- wxcli/commands/conference.py +328 -0
- wxcli/commands/configure.py +72 -0
- wxcli/commands/converged_recordings.py +347 -0
- wxcli/commands/converged_recordings_export.py +310 -0
- wxcli/commands/cq_playlists.py +42 -0
- wxcli/commands/cucm.py +2794 -0
- wxcli/commands/cucm_config.py +129 -0
- wxcli/commands/customer_assist.py +373 -0
- wxcli/commands/data_sources.py +227 -0
- wxcli/commands/dect_devices.py +787 -0
- wxcli/commands/device_configurations.py +77 -0
- wxcli/commands/device_dynamic_settings.py +320 -0
- wxcli/commands/device_settings.py +1489 -0
- wxcli/commands/devices.py +280 -0
- wxcli/commands/domains.py +142 -0
- wxcli/commands/ecm.py +178 -0
- wxcli/commands/emergency_services.py +827 -0
- wxcli/commands/events.py +83 -0
- wxcli/commands/external_voicemail.py +52 -0
- wxcli/commands/groups.py +206 -0
- wxcli/commands/guest_management.py +76 -0
- wxcli/commands/hds.py +340 -0
- wxcli/commands/hot_desk.py +67 -0
- wxcli/commands/hot_desking_members.py +118 -0
- wxcli/commands/hot_desking_portal.py +124 -0
- wxcli/commands/hunt_group.py +577 -0
- wxcli/commands/hybrid_clusters.py +71 -0
- wxcli/commands/hybrid_connectors.py +67 -0
- wxcli/commands/identity_org.py +159 -0
- wxcli/commands/init_playbook.py +155 -0
- wxcli/commands/licenses.py +106 -0
- wxcli/commands/live_monitoring.py +40 -0
- wxcli/commands/location_call_handling.py +577 -0
- wxcli/commands/location_schedules.py +341 -0
- wxcli/commands/location_settings.py +1297 -0
- wxcli/commands/location_voicemail.py +494 -0
- wxcli/commands/locations.py +336 -0
- wxcli/commands/meeting_captions.py +110 -0
- wxcli/commands/meeting_chats.py +63 -0
- wxcli/commands/meeting_invitees.py +234 -0
- wxcli/commands/meeting_messages.py +28 -0
- wxcli/commands/meeting_participants.py +278 -0
- wxcli/commands/meeting_polls.py +111 -0
- wxcli/commands/meeting_preferences.py +515 -0
- wxcli/commands/meeting_qa.py +78 -0
- wxcli/commands/meeting_qualities.py +43 -0
- wxcli/commands/meeting_reports.py +101 -0
- wxcli/commands/meeting_session_types.py +105 -0
- wxcli/commands/meeting_site.py +57 -0
- wxcli/commands/meeting_slido.py +44 -0
- wxcli/commands/meeting_summaries.py +92 -0
- wxcli/commands/meeting_tracking_codes.py +233 -0
- wxcli/commands/meeting_transcripts.py +230 -0
- wxcli/commands/meetings.py +1997 -0
- wxcli/commands/memberships.py +164 -0
- wxcli/commands/messages.py +213 -0
- wxcli/commands/mode_management.py +244 -0
- wxcli/commands/my_call_settings.py +3577 -0
- wxcli/commands/numbers.py +405 -0
- wxcli/commands/operating_modes.py +410 -0
- wxcli/commands/org_contacts.py +284 -0
- wxcli/commands/org_health_cli.py +55 -0
- wxcli/commands/org_settings.py +71 -0
- wxcli/commands/organizations.py +83 -0
- wxcli/commands/paging_group.py +257 -0
- wxcli/commands/partner_admins.py +141 -0
- wxcli/commands/partner_reports.py +188 -0
- wxcli/commands/partner_tags.py +216 -0
- wxcli/commands/people.py +279 -0
- wxcli/commands/person_call_settings.py +71 -0
- wxcli/commands/pstn.py +280 -0
- wxcli/commands/recording_report.py +154 -0
- wxcli/commands/report_templates.py +38 -0
- wxcli/commands/reports.py +144 -0
- wxcli/commands/resource_group_memberships.py +160 -0
- wxcli/commands/resource_groups.py +67 -0
- wxcli/commands/roles.py +63 -0
- wxcli/commands/room_tabs.py +160 -0
- wxcli/commands/rooms.py +225 -0
- wxcli/commands/scim_bulk.py +46 -0
- wxcli/commands/scim_groups.py +246 -0
- wxcli/commands/scim_schemas.py +82 -0
- wxcli/commands/scim_users.py +283 -0
- wxcli/commands/security_audit.py +54 -0
- wxcli/commands/service_apps.py +51 -0
- wxcli/commands/single_number_reach.py +209 -0
- wxcli/commands/team_memberships.py +155 -0
- wxcli/commands/teams.py +153 -0
- wxcli/commands/ucm_profile.py +42 -0
- wxcli/commands/update.py +219 -0
- wxcli/commands/user_settings.py +5116 -0
- wxcli/commands/video_mesh.py +1090 -0
- wxcli/commands/virtual_extensions.py +502 -0
- wxcli/commands/virtual_line_settings.py +2072 -0
- wxcli/commands/webhooks.py +176 -0
- wxcli/commands/wholesale_billing_reports.py +147 -0
- wxcli/commands/wholesale_provisioning.py +523 -0
- wxcli/commands/workspace_locations.py +339 -0
- wxcli/commands/workspace_metrics.py +103 -0
- wxcli/commands/workspace_personalization.py +70 -0
- wxcli/commands/workspace_settings.py +3347 -0
- wxcli/commands/workspaces.py +279 -0
- wxcli/commands/xapi.py +114 -0
- wxcli/config.py +139 -0
- wxcli/errors.py +77 -0
- wxcli/main.py +210 -0
- wxcli/migration/CLAUDE.md +106 -0
- wxcli/migration/__init__.py +1 -0
- wxcli/migration/advisory/CLAUDE.md +196 -0
- wxcli/migration/advisory/__init__.py +46 -0
- wxcli/migration/advisory/advisor.py +107 -0
- wxcli/migration/advisory/advisory_patterns.py +2552 -0
- wxcli/migration/advisory/recommendation_rules.py +835 -0
- wxcli/migration/cucm/CLAUDE.md +74 -0
- wxcli/migration/cucm/__init__.py +5 -0
- wxcli/migration/cucm/connection.py +265 -0
- wxcli/migration/cucm/discovery.py +225 -0
- wxcli/migration/cucm/extractors/__init__.py +1 -0
- wxcli/migration/cucm/extractors/announcements.py +92 -0
- wxcli/migration/cucm/extractors/base.py +90 -0
- wxcli/migration/cucm/extractors/device_profiles.py +98 -0
- wxcli/migration/cucm/extractors/devices.py +193 -0
- wxcli/migration/cucm/extractors/e911.py +103 -0
- wxcli/migration/cucm/extractors/features.py +309 -0
- wxcli/migration/cucm/extractors/helpers.py +73 -0
- wxcli/migration/cucm/extractors/informational.py +295 -0
- wxcli/migration/cucm/extractors/locations.py +221 -0
- wxcli/migration/cucm/extractors/moh.py +100 -0
- wxcli/migration/cucm/extractors/remote_destinations.py +96 -0
- wxcli/migration/cucm/extractors/routing.py +493 -0
- wxcli/migration/cucm/extractors/shared_lines.py +146 -0
- wxcli/migration/cucm/extractors/templates.py +229 -0
- wxcli/migration/cucm/extractors/tier4.py +173 -0
- wxcli/migration/cucm/extractors/users.py +240 -0
- wxcli/migration/cucm/extractors/voicemail.py +243 -0
- wxcli/migration/cucm/extractors/workspaces.py +88 -0
- wxcli/migration/cucm/unity_connection.py +304 -0
- wxcli/migration/execute/CLAUDE.md +372 -0
- wxcli/migration/execute/__init__.py +303 -0
- wxcli/migration/execute/batch.py +277 -0
- wxcli/migration/execute/dependency.py +483 -0
- wxcli/migration/execute/engine.py +964 -0
- wxcli/migration/execute/handlers.py +2232 -0
- wxcli/migration/execute/planner.py +1939 -0
- wxcli/migration/execute/runtime.py +571 -0
- wxcli/migration/export/CLAUDE.md +49 -0
- wxcli/migration/export/__init__.py +8 -0
- wxcli/migration/export/csv_export.py +126 -0
- wxcli/migration/export/deployment_plan.py +479 -0
- wxcli/migration/export/json_export.py +60 -0
- wxcli/migration/models.py +941 -0
- wxcli/migration/phone_models.py +50 -0
- wxcli/migration/preflight/CLAUDE.md +52 -0
- wxcli/migration/preflight/__init__.py +89 -0
- wxcli/migration/preflight/checks.py +911 -0
- wxcli/migration/preflight/runner.py +293 -0
- wxcli/migration/rate_limiter.py +144 -0
- wxcli/migration/report/CLAUDE.md +245 -0
- wxcli/migration/report/__init__.py +7 -0
- wxcli/migration/report/appendix.py +2437 -0
- wxcli/migration/report/assembler.py +183 -0
- wxcli/migration/report/charts.py +263 -0
- wxcli/migration/report/executive.py +776 -0
- wxcli/migration/report/explainer.py +704 -0
- wxcli/migration/report/helpers.py +74 -0
- wxcli/migration/report/ingest.py +152 -0
- wxcli/migration/report/notice_templates.py +192 -0
- wxcli/migration/report/score.py +375 -0
- wxcli/migration/report/styles.py +1052 -0
- wxcli/migration/report/user_diff.py +1052 -0
- wxcli/migration/report/user_notice.py +425 -0
- wxcli/migration/state.py +139 -0
- wxcli/migration/store.py +860 -0
- wxcli/migration/transform/CLAUDE.md +107 -0
- wxcli/migration/transform/__init__.py +12 -0
- wxcli/migration/transform/analysis_pipeline.py +453 -0
- wxcli/migration/transform/analyzers/__init__.py +142 -0
- wxcli/migration/transform/analyzers/css_permission.py +189 -0
- wxcli/migration/transform/analyzers/css_routing.py +335 -0
- wxcli/migration/transform/analyzers/device_compatibility.py +122 -0
- wxcli/migration/transform/analyzers/dn_ambiguity.py +131 -0
- wxcli/migration/transform/analyzers/duplicate_user.py +221 -0
- wxcli/migration/transform/analyzers/extension_conflict.py +173 -0
- wxcli/migration/transform/analyzers/feature_approximation.py +227 -0
- wxcli/migration/transform/analyzers/layout_overflow.py +174 -0
- wxcli/migration/transform/analyzers/location_ambiguity.py +184 -0
- wxcli/migration/transform/analyzers/missing_data.py +300 -0
- wxcli/migration/transform/analyzers/selective_call_handling.py +394 -0
- wxcli/migration/transform/analyzers/shared_line.py +170 -0
- wxcli/migration/transform/analyzers/voicemail_compatibility.py +267 -0
- wxcli/migration/transform/analyzers/workspace_license.py +212 -0
- wxcli/migration/transform/cross_reference.py +1136 -0
- wxcli/migration/transform/cucm_pattern.py +246 -0
- wxcli/migration/transform/decisions.py +301 -0
- wxcli/migration/transform/e164.py +145 -0
- wxcli/migration/transform/engine.py +256 -0
- wxcli/migration/transform/mappers/CLAUDE.md +123 -0
- wxcli/migration/transform/mappers/__init__.py +76 -0
- wxcli/migration/transform/mappers/announcement_mapper.py +122 -0
- wxcli/migration/transform/mappers/base.py +190 -0
- wxcli/migration/transform/mappers/button_template_mapper.py +186 -0
- wxcli/migration/transform/mappers/call_forwarding_mapper.py +228 -0
- wxcli/migration/transform/mappers/call_settings_mapper.py +144 -0
- wxcli/migration/transform/mappers/css_mapper.py +868 -0
- wxcli/migration/transform/mappers/dect_mapper.py +367 -0
- wxcli/migration/transform/mappers/device_layout_mapper.py +289 -0
- wxcli/migration/transform/mappers/device_mapper.py +227 -0
- wxcli/migration/transform/mappers/device_profile_mapper.py +190 -0
- wxcli/migration/transform/mappers/device_settings_mapper.py +464 -0
- wxcli/migration/transform/mappers/e911_mapper.py +129 -0
- wxcli/migration/transform/mappers/ecbn_mapper.py +263 -0
- wxcli/migration/transform/mappers/executive_assistant_mapper.py +156 -0
- wxcli/migration/transform/mappers/feature_mapper.py +1179 -0
- wxcli/migration/transform/mappers/line_mapper.py +310 -0
- wxcli/migration/transform/mappers/location_mapper.py +235 -0
- wxcli/migration/transform/mappers/moh_mapper.py +114 -0
- wxcli/migration/transform/mappers/monitoring_mapper.py +221 -0
- wxcli/migration/transform/mappers/receptionist_mapper.py +245 -0
- wxcli/migration/transform/mappers/routing_mapper.py +821 -0
- wxcli/migration/transform/mappers/snr_mapper.py +201 -0
- wxcli/migration/transform/mappers/softkey_mapper.py +205 -0
- wxcli/migration/transform/mappers/user_mapper.py +264 -0
- wxcli/migration/transform/mappers/voicemail_group_mapper.py +286 -0
- wxcli/migration/transform/mappers/voicemail_mapper.py +514 -0
- wxcli/migration/transform/mappers/workspace_mapper.py +464 -0
- wxcli/migration/transform/normalizers.py +2008 -0
- wxcli/migration/transform/pattern_converter.py +106 -0
- wxcli/migration/transform/pipeline.py +271 -0
- wxcli/migration/transform/rules.py +255 -0
- wxcli/org_health/CLAUDE.md +63 -0
- wxcli/org_health/__init__.py +7 -0
- wxcli/org_health/analyze.py +93 -0
- wxcli/org_health/checks.py +458 -0
- wxcli/org_health/collector.py +62 -0
- wxcli/org_health/models.py +78 -0
- wxcli/org_health/report.py +300 -0
- wxcli/output.py +101 -0
- wxcli-1.2.0.dist-info/METADATA +505 -0
- wxcli-1.2.0.dist-info/RECORD +413 -0
- wxcli-1.2.0.dist-info/WHEEL +5 -0
- wxcli-1.2.0.dist-info/entry_points.txt +2 -0
- wxcli-1.2.0.dist-info/licenses/LICENSE +191 -0
- wxcli-1.2.0.dist-info/scm_file_list.json +751 -0
- wxcli-1.2.0.dist-info/scm_version.json +8 -0
- wxcli-1.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,938 @@
|
|
|
1
|
+
<!-- Not directly verified via CLI — documents wxcadm library (not generated CLI commands) -->
|
|
2
|
+
<!-- wxcadm v4.6.1 review 2026-03-27: All v4.5.0–v4.6.1 changes verified present. LocationList(org) signature, Location(org=) constructor, logitude→longitude typo fix, Location.set_default_moh/upload_moh_file removal, workspace_location removal, external_caller_id_name Optional[str] return type — all accurately documented. No discrepancies found. -->
|
|
3
|
+
# wxcadm Location Management
|
|
4
|
+
|
|
5
|
+
Reference for location CRUD, calling enablement, schedules, and location-level features in `wxcadm`.
|
|
6
|
+
|
|
7
|
+
Source files: `wxcadm/location.py`, `wxcadm/location_features.py`
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<!-- Updated by playbook session 2026-03-18 -->
|
|
12
|
+
## When to Use wxcadm vs Raw HTTP
|
|
13
|
+
|
|
14
|
+
| Use wxcadm when | Use raw HTTP when |
|
|
15
|
+
|---|---|
|
|
16
|
+
| You need **batch operations across all locations** — `LocationList` caches the full list and provides filtered lookups without repeated API calls | You're doing CRUD on a single known location |
|
|
17
|
+
| You want **`enable_webex_calling()`** which orchestrates multiple API calls (PSTN, zone assignment, phone number assignment) in one method | You need to configure a specific location setting (internal dialing, voicemail policy, etc.) |
|
|
18
|
+
| You need **location-scoped feature lists** — `location.call_queues`, `location.hunt_groups`, etc. auto-filter to that location | You want direct control over which endpoints are called |
|
|
19
|
+
| You want **schedule management** via `LocationSchedule` with event CRUD | You're building automation against well-known location endpoints |
|
|
20
|
+
|
|
21
|
+
> **Note:** The playbook uses raw HTTP via `api.session.rest_*()` for location CRUD and settings configuration. Location endpoints are straightforward REST resources. wxcadm's main value here is batch discovery (iterating all locations with cached data) and the `enable_webex_calling()` orchestration method, which bundles multiple setup steps into one call.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Table of Contents
|
|
26
|
+
|
|
27
|
+
1. [LocationList](#locationlist)
|
|
28
|
+
2. [Location](#location)
|
|
29
|
+
- [Core Properties](#core-properties)
|
|
30
|
+
- [Calling Enablement](#calling-enablement)
|
|
31
|
+
- [Calling Configuration](#calling-configuration)
|
|
32
|
+
- [Number Management](#number-management)
|
|
33
|
+
- [Emergency Services](#emergency-services)
|
|
34
|
+
- [Schedules](#schedules)
|
|
35
|
+
- [Outgoing Call Permissions](#outgoing-call-permissions)
|
|
36
|
+
- [Feature Access Properties](#feature-access-properties)
|
|
37
|
+
- [Floor Management](#floor-management)
|
|
38
|
+
- [Monitoring](#monitoring)
|
|
39
|
+
- [Delete](#delete)
|
|
40
|
+
3. [Location Features](#location-features)
|
|
41
|
+
- [LocationSchedule](#locationschedule)
|
|
42
|
+
- [VoicePortal](#voiceportal)
|
|
43
|
+
- [CallParkExtension](#callparkextension)
|
|
44
|
+
- [PagingGroup](#paginggroup)
|
|
45
|
+
- [OutgoingPermissionDigitPattern](#outgoingpermissiondigitpattern)
|
|
46
|
+
- [VoicemailGroup](#voicemailgroup)
|
|
47
|
+
4. [wxcadm vs wxc_sdk](#wxcadm-vs-wxc_sdk)
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## LocationList
|
|
52
|
+
|
|
53
|
+
`LocationList` extends `collections.UserList`. It is created automatically when you access `org.locations` and fetches all locations from the Webex `v1/locations` API on initialization.
|
|
54
|
+
|
|
55
|
+
### Constructor
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
LocationList(org: wxcadm.Org)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Fetches all locations on init. The list is iterable and indexable like a normal Python list.
|
|
62
|
+
|
|
63
|
+
### Methods
|
|
64
|
+
|
|
65
|
+
#### `refresh()`
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
def refresh(self) -> None
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Re-fetches the full location list from Webex. Call this after creating or deleting locations outside the list.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
#### `get(id=None, name=None, spark_id=None)`
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
def get(self, id: str = None, name: str = None, spark_id: str = None) -> Optional[Location]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Find a Location by ID, name, or Spark ID. Searches in that priority order. Returns `None` if no match.
|
|
82
|
+
|
|
83
|
+
Raises `ValueError` if called with no arguments.
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
loc = org.locations.get(name="Main Office")
|
|
87
|
+
loc = org.locations.get(id="Y2lzY29...")
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
#### `create(...)`
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
def create(self,
|
|
96
|
+
name: str,
|
|
97
|
+
time_zone: str,
|
|
98
|
+
preferred_language: str,
|
|
99
|
+
address: dict,
|
|
100
|
+
latitude: Optional[str] = None,
|
|
101
|
+
longitude: Optional[str] = None) -> Location
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Creates a new location via `POST v1/locations`. Automatically refreshes the list and returns the new `Location` instance.
|
|
105
|
+
|
|
106
|
+
**Address dict format:**
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
{
|
|
110
|
+
"address1": "100 N. Main",
|
|
111
|
+
"address2": "Suite 200", # optional
|
|
112
|
+
"city": "Houston",
|
|
113
|
+
"state": "TX",
|
|
114
|
+
"postalCode": "32123",
|
|
115
|
+
"country": "US"
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
loc = org.locations.create(
|
|
121
|
+
name="Branch Office",
|
|
122
|
+
time_zone="America/New_York",
|
|
123
|
+
preferred_language="en_US",
|
|
124
|
+
address={"address1": "50 Elm St", "city": "Raleigh", "state": "NC", "postalCode": "27601", "country": "US"}
|
|
125
|
+
)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
#### `webex_calling(enabled=True, single=False)`
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
def webex_calling(self, enabled: bool = True, single: bool = False) -> Location | list[Location]
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Filters locations by Webex Calling enablement status. Uses the bulk `v1/telephony/config/locations` API (added in v4.3.9) instead of per-location calls.
|
|
137
|
+
|
|
138
|
+
- `enabled=True` (default): returns locations that have Webex Calling
|
|
139
|
+
- `enabled=False`: returns locations that do NOT have Webex Calling
|
|
140
|
+
- `single=True`: returns just the first matching Location (useful for API calls that only need one WxC location)
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
wxc_locations = org.locations.webex_calling()
|
|
144
|
+
non_wxc = org.locations.webex_calling(enabled=False)
|
|
145
|
+
one_loc = org.locations.webex_calling(single=True)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
#### `with_pstn(has_pstn=True)`
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
def with_pstn(self, has_pstn: bool = True) -> list[Location]
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Filters Webex Calling locations by whether they have a PSTN provider configured. Calls `webex_calling(enabled=True)` internally, then checks `loc.pstn.provider`.
|
|
157
|
+
|
|
158
|
+
#### `without_pstn()`
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
def without_pstn(self) -> list[Location]
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Alias for `with_pstn(has_pstn=False)`.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Location
|
|
169
|
+
|
|
170
|
+
The `Location` class represents a single Webex location. Instances are typically created by `LocationList`, not manually.
|
|
171
|
+
|
|
172
|
+
### Constructor
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
Location(org: wxcadm.Org,
|
|
176
|
+
location_id: str,
|
|
177
|
+
name: str,
|
|
178
|
+
time_zone: str,
|
|
179
|
+
preferred_language: str,
|
|
180
|
+
announcement_language: str = None,
|
|
181
|
+
address: dict = None)
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Core Properties
|
|
185
|
+
|
|
186
|
+
| Property | Type | Description |
|
|
187
|
+
|----------|------|-------------|
|
|
188
|
+
| `id` | `str` | Webex ID of the location |
|
|
189
|
+
| `name` | `str` | Location name |
|
|
190
|
+
| `address` | `dict` | Address dictionary |
|
|
191
|
+
| `time_zone` | `str` | Timezone string (e.g. `America/Chicago`) |
|
|
192
|
+
| `preferred_language` | `str` | Language for phones/menus (e.g. `en_US`) |
|
|
193
|
+
| `announcement_language` | `str` | Language for audio announcements |
|
|
194
|
+
| `org_id` | `str` | Org ID (delegates to `self.org.id`) |
|
|
195
|
+
| `spark_id` | `str` | Decoded Spark ID (underlying service ID) |
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
### Calling Enablement
|
|
200
|
+
|
|
201
|
+
#### `calling_enabled` (property + setter)
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
@property
|
|
205
|
+
def calling_enabled(self) -> bool
|
|
206
|
+
|
|
207
|
+
@calling_enabled.setter
|
|
208
|
+
def calling_enabled(self, value: bool)
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Checks whether the location has Webex Calling by hitting `GET v1/telephony/config/locations/{id}`. The result is cached after the first call. The setter allows manual override without an API call (used internally by `LocationList.webex_calling()`).
|
|
212
|
+
|
|
213
|
+
#### `enable_webex_calling()`
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
def enable_webex_calling(self) -> bool
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Enables Webex Calling on the location via `PUT v1/telephony/config/locations`. No-ops if already enabled. Returns `True` on success.
|
|
220
|
+
|
|
221
|
+
**Gotcha:** If `address2` is an empty string `''`, the API will reject it. This method cleans it to `None` before sending.
|
|
222
|
+
|
|
223
|
+
#### `calling_config` (property)
|
|
224
|
+
|
|
225
|
+
```python
|
|
226
|
+
@property
|
|
227
|
+
def calling_config(self) -> Optional[dict]
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Returns the full Webex Calling configuration dict for the location. Cached after first access. Returns `None` if location is not Calling-enabled.
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
### Calling Configuration
|
|
235
|
+
|
|
236
|
+
#### `external_caller_id_name` (property)
|
|
237
|
+
|
|
238
|
+
```python
|
|
239
|
+
@property
|
|
240
|
+
def external_caller_id_name(self) -> Optional[str]
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
The default external Caller ID name for the location.
|
|
244
|
+
|
|
245
|
+
#### `set_external_caller_id_name(name)`
|
|
246
|
+
|
|
247
|
+
```python
|
|
248
|
+
def set_external_caller_id_name(self, name: str) -> bool
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Sets the default external Caller ID name. Clears the cached `_calling_config` so the next access re-fetches.
|
|
252
|
+
|
|
253
|
+
#### `routing_prefix` (property)
|
|
254
|
+
|
|
255
|
+
```python
|
|
256
|
+
@property
|
|
257
|
+
def routing_prefix(self) -> Optional[str]
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
The routing prefix (location code) for the location. Derived from `calling_config`.
|
|
261
|
+
|
|
262
|
+
#### `set_routing_prefix(prefix)`
|
|
263
|
+
|
|
264
|
+
```python
|
|
265
|
+
def set_routing_prefix(self, prefix: str) -> bool
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Sets the routing prefix via `PUT v1/telephony/config/locations/{id}`.
|
|
269
|
+
|
|
270
|
+
#### `set_announcement_language(language, update_users=False, update_features=False)`
|
|
271
|
+
|
|
272
|
+
```python
|
|
273
|
+
def set_announcement_language(self,
|
|
274
|
+
language: str,
|
|
275
|
+
update_users: bool = False,
|
|
276
|
+
update_features: bool = False) -> bool
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Sets the announcement language for the location. With optional flags to propagate to existing users/workspaces and features.
|
|
280
|
+
|
|
281
|
+
**Important:** Calling without `update_users`/`update_features` only changes the default for *new* users/features. Existing ones keep their current language unless you pass `True`.
|
|
282
|
+
|
|
283
|
+
```python
|
|
284
|
+
# Change default only
|
|
285
|
+
loc.set_announcement_language("es_ES")
|
|
286
|
+
|
|
287
|
+
# Change and update all existing users and features
|
|
288
|
+
loc.set_announcement_language("es_ES", update_users=True, update_features=True)
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
#### `unknown_extension_policy` (property)
|
|
292
|
+
|
|
293
|
+
```python
|
|
294
|
+
@property
|
|
295
|
+
def unknown_extension_policy(self) -> dict
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Returns `{'enabled': bool, 'route': Trunk | RouteGroup | None}`. Controls whether unknown extensions are routed to premises via a Trunk or Route Group.
|
|
299
|
+
|
|
300
|
+
#### `set_unknown_extension_policy(route)`
|
|
301
|
+
|
|
302
|
+
```python
|
|
303
|
+
def set_unknown_extension_policy(self, route: Union[wxcadm.Trunk, wxcadm.RouteGroup, str]) -> bool
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Pass a `Trunk` or `RouteGroup` to enable, or the string `'disabled'` to disable.
|
|
307
|
+
|
|
308
|
+
```python
|
|
309
|
+
trunk = org.call_routing.trunks.get(name="PBX Trunk")
|
|
310
|
+
loc.set_unknown_extension_policy(trunk)
|
|
311
|
+
|
|
312
|
+
# To disable:
|
|
313
|
+
loc.set_unknown_extension_policy('disabled')
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
### Number Management
|
|
319
|
+
|
|
320
|
+
#### `numbers` (property)
|
|
321
|
+
|
|
322
|
+
```python
|
|
323
|
+
@property
|
|
324
|
+
def numbers(self) -> Optional[NumberList]
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
All numbers assigned to this location. Returns `None` if not a Calling location.
|
|
328
|
+
|
|
329
|
+
#### `available_numbers` (property)
|
|
330
|
+
|
|
331
|
+
```python
|
|
332
|
+
@property
|
|
333
|
+
def available_numbers(self) -> Optional[list[dict]]
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Numbers that are available (unassigned) at this location. Includes both Active and Inactive numbers so numbers can be assigned prior to activation/porting.
|
|
337
|
+
|
|
338
|
+
#### `main_number` (property)
|
|
339
|
+
|
|
340
|
+
```python
|
|
341
|
+
@property
|
|
342
|
+
def main_number(self) -> Number
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
The main number for the location. Derived from `calling_config['callingLineId']['phoneNumber']`.
|
|
346
|
+
|
|
347
|
+
#### `set_main_number(number)`
|
|
348
|
+
|
|
349
|
+
```python
|
|
350
|
+
def set_main_number(self, number: Union[Number, str]) -> bool
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Sets the main number. Accepts a `Number` instance or a phone number string.
|
|
354
|
+
|
|
355
|
+
Raises `wxcadm.APIError` if the number is rejected by Webex.
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
### Emergency Services
|
|
360
|
+
|
|
361
|
+
#### `ecbn` (property)
|
|
362
|
+
|
|
363
|
+
```python
|
|
364
|
+
@property
|
|
365
|
+
def ecbn(self) -> dict
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
Emergency Callback Number settings for the location.
|
|
369
|
+
|
|
370
|
+
#### `set_ecbn(value)`
|
|
371
|
+
|
|
372
|
+
```python
|
|
373
|
+
def set_ecbn(self, value: Union[str, Person, Workspace, VirtualLine, HuntGroup]) -> bool
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
Set the ECBN. Pass the string `'location'` to use the location number, or a `Person`, `Workspace`, `VirtualLine`, or `HuntGroup` to use a member's number.
|
|
377
|
+
|
|
378
|
+
```python
|
|
379
|
+
loc.set_ecbn('location')
|
|
380
|
+
loc.set_ecbn(org.people.get(email="jane@example.com"))
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
#### `enhanced_emergency_calling` (property)
|
|
384
|
+
|
|
385
|
+
```python
|
|
386
|
+
@property
|
|
387
|
+
def enhanced_emergency_calling(self) -> LocationEmergencySettings
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Returns a `LocationEmergencySettings` object with boolean attributes `integration` and `routing` (RedSky integration status).
|
|
391
|
+
|
|
392
|
+
#### `set_enhanced_emergency_calling(mode)`
|
|
393
|
+
|
|
394
|
+
```python
|
|
395
|
+
def set_enhanced_emergency_calling(self, mode: str) -> dict
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
Set the RedSky Enhanced Emergency Calling mode. Valid modes:
|
|
399
|
+
|
|
400
|
+
| Mode | Effect |
|
|
401
|
+
|------|--------|
|
|
402
|
+
| `'none'` | Opt out of enhanced emergency calling |
|
|
403
|
+
| `'integration'` | Integrate with RedSky (HELD data + 933 test calls) |
|
|
404
|
+
| `'routing'` | Route 911 calls through RedSky |
|
|
405
|
+
|
|
406
|
+
**Known issue (from source):** Running this method with any value will cause the location to show a compliance warning in Control Hub. The config is correct but the warning can only be cleared manually in Control Hub.
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
### Schedules
|
|
411
|
+
|
|
412
|
+
#### `schedules` (property)
|
|
413
|
+
|
|
414
|
+
```python
|
|
415
|
+
@property
|
|
416
|
+
def schedules(self) -> Optional[list[LocationSchedule]]
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
Returns a list of `LocationSchedule` instances (business hours and holidays). Returns `None` if not a Calling location.
|
|
420
|
+
|
|
421
|
+
See [LocationSchedule](#locationschedule) below for full schedule management.
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
### Outgoing Call Permissions
|
|
426
|
+
|
|
427
|
+
#### `outgoing_call_permissions` (property)
|
|
428
|
+
|
|
429
|
+
```python
|
|
430
|
+
@property
|
|
431
|
+
def outgoing_call_permissions(self) -> Optional[list]
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
The `callingPermissions` list for the location. Each entry is a dict with call type and permission settings.
|
|
435
|
+
|
|
436
|
+
#### `set_outgoing_call_permissions(outgoing_call_permissions)`
|
|
437
|
+
|
|
438
|
+
```python
|
|
439
|
+
def set_outgoing_call_permissions(self, outgoing_call_permissions: list) -> Optional[bool]
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
Set outgoing call permissions. The easiest approach is to read the current list, modify it, and pass it back.
|
|
443
|
+
|
|
444
|
+
```python
|
|
445
|
+
perms = loc.outgoing_call_permissions
|
|
446
|
+
# Modify perms...
|
|
447
|
+
loc.set_outgoing_call_permissions(perms)
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
Raises `ValueError` if the argument is not a list.
|
|
451
|
+
|
|
452
|
+
#### `outgoing_permission_digit_patterns` (property)
|
|
453
|
+
|
|
454
|
+
```python
|
|
455
|
+
@property
|
|
456
|
+
def outgoing_permission_digit_patterns(self) -> OutgoingPermissionDigitPatternList
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
Returns an `OutgoingPermissionDigitPatternList` for creating/managing digit pattern-based outgoing call rules. See [OutgoingPermissionDigitPattern](#outgoingpermissiondigitpattern) below.
|
|
460
|
+
|
|
461
|
+
---
|
|
462
|
+
|
|
463
|
+
### Feature Access Properties
|
|
464
|
+
|
|
465
|
+
These properties return feature-specific list objects scoped to the location. All return `None` if the location is not Webex Calling enabled (except where noted).
|
|
466
|
+
|
|
467
|
+
| Property | Return Type | Description |
|
|
468
|
+
|----------|-------------|-------------|
|
|
469
|
+
| `hunt_groups` | `HuntGroupList` | Hunt groups at this location |
|
|
470
|
+
| `call_queues` | `CallQueueList` | Call queues at this location |
|
|
471
|
+
| `auto_attendants` | `AutoAttendantList` | Auto attendants at this location |
|
|
472
|
+
| `pickup_groups` | `PickupGroupList` | Pickup groups at this location |
|
|
473
|
+
| `park_extensions` | `list[CallParkExtension]` | Call park extensions at this location |
|
|
474
|
+
| `dect_networks` | `DECTNetworkList` | DECT networks at this location |
|
|
475
|
+
| `virtual_lines` | `VirtualLineList` | Virtual lines at this location |
|
|
476
|
+
| `translation_patterns` | `TranslationPatternList` | Translation patterns at this location |
|
|
477
|
+
| `workspaces` | `WorkspaceList` | Workspaces at this location |
|
|
478
|
+
| `people` | `list` | People assigned to this location (delegates to `org.people.get(location=self)`) |
|
|
479
|
+
| `announcements` | `list[Announcement]` | Location-level announcements (excludes org-level) |
|
|
480
|
+
| `voice_portal` | `VoicePortal` | Voice portal for this location |
|
|
481
|
+
| `recording_vendor` | `LocationRecordingVendorSelection` | Recording vendor selection |
|
|
482
|
+
| `pstn` | `LocationPSTN` | PSTN configuration for this location |
|
|
483
|
+
|
|
484
|
+
#### `create_park_extension(name, extension)`
|
|
485
|
+
|
|
486
|
+
```python
|
|
487
|
+
def create_park_extension(self, name: str, extension: str) -> str
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
Creates a new Call Park Extension. Returns the ID of the created extension.
|
|
491
|
+
|
|
492
|
+
---
|
|
493
|
+
|
|
494
|
+
### Floor Management
|
|
495
|
+
|
|
496
|
+
#### `floors` (property)
|
|
497
|
+
|
|
498
|
+
```python
|
|
499
|
+
@property
|
|
500
|
+
def floors(self) -> LocationFloorList
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
Returns a `LocationFloorList` (extends `UserList`) of `LocationFloor` instances.
|
|
504
|
+
|
|
505
|
+
#### LocationFloorList Methods
|
|
506
|
+
|
|
507
|
+
```python
|
|
508
|
+
def refresh(self) -> None # Re-fetch from API
|
|
509
|
+
def create(self, floor_number: int, name: str) -> LocationFloor # Create a floor
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
`create()` raises `ValueError` if the floor number already exists.
|
|
513
|
+
|
|
514
|
+
#### LocationFloor
|
|
515
|
+
|
|
516
|
+
| Attribute | Type | Description |
|
|
517
|
+
|-----------|------|-------------|
|
|
518
|
+
| `id` | `str` | Floor ID |
|
|
519
|
+
| `floor_number` | `int` | Numeric floor within the building |
|
|
520
|
+
| `name` | `str` | Display name (e.g. "Basement", "2nd Floor") |
|
|
521
|
+
|
|
522
|
+
```python
|
|
523
|
+
def update(self, floor_number: Optional[int] = None, name: Optional[str] = None) -> bool
|
|
524
|
+
def delete(self) -> bool
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
---
|
|
528
|
+
|
|
529
|
+
### Monitoring
|
|
530
|
+
|
|
531
|
+
#### `get_all_monitoring()`
|
|
532
|
+
|
|
533
|
+
```python
|
|
534
|
+
def get_all_monitoring(self) -> dict
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
Returns a dict showing who is monitoring whom at this location:
|
|
538
|
+
|
|
539
|
+
```python
|
|
540
|
+
{
|
|
541
|
+
'people': { person_instance: [list_of_monitors] },
|
|
542
|
+
'workspaces': { workspace_instance: [list_of_monitors] }
|
|
543
|
+
}
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
Iterates over all people and Webex Calling workspaces at the location, collecting their monitored elements.
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
### Delete
|
|
551
|
+
|
|
552
|
+
#### `delete()`
|
|
553
|
+
|
|
554
|
+
```python
|
|
555
|
+
def delete(self) -> bool
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
**Always returns `False`.** Location deletion is not supported via the Webex API. This stub exists so users are not searching for a missing method. Must be done in Control Hub.
|
|
559
|
+
|
|
560
|
+
---
|
|
561
|
+
|
|
562
|
+
## Location Features
|
|
563
|
+
|
|
564
|
+
Defined in `wxcadm/location_features.py`. These classes represent features that are scoped to a specific location.
|
|
565
|
+
|
|
566
|
+
### LocationSchedule
|
|
567
|
+
|
|
568
|
+
```python
|
|
569
|
+
@dataclass
|
|
570
|
+
class LocationSchedule:
|
|
571
|
+
location: wxcadm.Location
|
|
572
|
+
id: str
|
|
573
|
+
name: str
|
|
574
|
+
type: str # 'businessHours' or 'holidays'
|
|
575
|
+
config: dict # auto-populated on init
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
Fetches its full configuration from `v1/telephony/config/locations/{loc_id}/schedules/{type}/{id}` on initialization.
|
|
579
|
+
|
|
580
|
+
#### `refresh_config()`
|
|
581
|
+
|
|
582
|
+
```python
|
|
583
|
+
def refresh_config(self) -> None
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
Re-fetches the schedule config from the API.
|
|
587
|
+
|
|
588
|
+
#### `add_holiday(name, date, recur=False, recurrence=None)`
|
|
589
|
+
|
|
590
|
+
```python
|
|
591
|
+
def add_holiday(self, name: str, date: str, recur: bool = False, recurrence: Optional[dict] = None) -> bool
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
Adds an all-day holiday event. Only works on `holidays` type schedules (raises `TypeError` otherwise).
|
|
595
|
+
|
|
596
|
+
- `date` format: `YYYY-MM-DD`
|
|
597
|
+
- If `recur=True` and no `recurrence` dict is given, defaults to yearly recurrence on the same month/day (works for fixed-date holidays like Christmas)
|
|
598
|
+
- For floating holidays (e.g. Thanksgiving), pass a custom recurrence dict:
|
|
599
|
+
|
|
600
|
+
```python
|
|
601
|
+
recurrence = {
|
|
602
|
+
'recurForEver': True,
|
|
603
|
+
'recurYearlyByDay': {
|
|
604
|
+
'day': 'THURSDAY',
|
|
605
|
+
'week': 'FOURTH',
|
|
606
|
+
'month': 'NOVEMBER'
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
schedule.add_holiday("Thanksgiving", "2026-11-26", recur=True, recurrence=recurrence)
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
#### `create_event(name, start_date, end_date, ...)`
|
|
613
|
+
|
|
614
|
+
```python
|
|
615
|
+
def create_event(self,
|
|
616
|
+
name: str,
|
|
617
|
+
start_date: str,
|
|
618
|
+
end_date: str,
|
|
619
|
+
start_time: str = "",
|
|
620
|
+
end_time: str = "",
|
|
621
|
+
all_day: bool = False,
|
|
622
|
+
recurrence: Optional[dict] = None) -> bool
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
Generic event creation for either schedule type. If `all_day=False`, both `start_time` and `end_time` are required (raises `ValueError` otherwise).
|
|
626
|
+
|
|
627
|
+
Recurrence dict example (every weekday):
|
|
628
|
+
|
|
629
|
+
```python
|
|
630
|
+
recurrence = {
|
|
631
|
+
'recurForEver': True,
|
|
632
|
+
'recurWeekly': {
|
|
633
|
+
'monday': True
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
#### `update_event(id, ...)`
|
|
639
|
+
|
|
640
|
+
```python
|
|
641
|
+
def update_event(self,
|
|
642
|
+
id: str,
|
|
643
|
+
name: str = None,
|
|
644
|
+
start_date: str = None,
|
|
645
|
+
end_date: str = None,
|
|
646
|
+
start_time: str = None,
|
|
647
|
+
end_time: str = None,
|
|
648
|
+
all_day: bool = None,
|
|
649
|
+
recurrence: dict = None) -> bool
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
Updates an existing event by ID. Fetches the current config for the event, merges in provided values, and PUTs it back.
|
|
653
|
+
|
|
654
|
+
**Known bug in wxcadm:** The `update_event()` method's API URL is truncated — it PUTs to `v1/telephony/config/` instead of the full schedule/event path (`v1/telephony/config/locations/{loc_id}/schedules/{type}/{id}/events/{event_id}`). This means updates will fail with an API error. Workaround: use raw HTTP via `api.session.rest_put()` with the correct URL.
|
|
655
|
+
|
|
656
|
+
#### `delete_event(event)`
|
|
657
|
+
|
|
658
|
+
```python
|
|
659
|
+
def delete_event(self, event: str) -> bool
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
Deletes an event by name or ID (both are unique within a schedule).
|
|
663
|
+
|
|
664
|
+
#### `get_event_config_by_id(id)`
|
|
665
|
+
|
|
666
|
+
```python
|
|
667
|
+
def get_event_config_by_id(self, id: str) -> Optional[dict]
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
Returns the raw event dict from the schedule config for a given event ID. Useful for inspecting or modifying event data.
|
|
671
|
+
|
|
672
|
+
#### `clone(target_location=None, name=None)`
|
|
673
|
+
|
|
674
|
+
```python
|
|
675
|
+
def clone(self,
|
|
676
|
+
target_location: Optional[wxcadm.Location] = None,
|
|
677
|
+
name: Optional[str] = None) -> str
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
Clones the schedule. You must provide at least one of `target_location` or `name`.
|
|
681
|
+
|
|
682
|
+
- To clone to another location (same name): `schedule.clone(target_location=other_loc)`
|
|
683
|
+
- To clone within the same location (new name): `schedule.clone(name="After Hours v2")`
|
|
684
|
+
- Both: `schedule.clone(target_location=other_loc, name="Custom Name")`
|
|
685
|
+
|
|
686
|
+
Returns the ID of the newly created schedule.
|
|
687
|
+
|
|
688
|
+
---
|
|
689
|
+
|
|
690
|
+
### VoicePortal
|
|
691
|
+
|
|
692
|
+
```python
|
|
693
|
+
@dataclass
|
|
694
|
+
class VoicePortal(RealtimeClass):
|
|
695
|
+
location: wxcadm.Location
|
|
696
|
+
id: str # auto-populated
|
|
697
|
+
language: str
|
|
698
|
+
language_code: str
|
|
699
|
+
extension: str
|
|
700
|
+
phone_number: str
|
|
701
|
+
first_name: str
|
|
702
|
+
last_name: str
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
Extends `RealtimeClass` -- changing attributes directly pushes updates to Webex immediately (unlike other wxcadm classes that require explicit save calls).
|
|
706
|
+
|
|
707
|
+
**How auto-push works:** `_api_fields` is initialized with `['phone_number', 'extension']`, but `RealtimeClass.__init__` appends ALL fields from the API GET response to the same list. The `__setattr__` override fires on ANY attribute change after initialization, PUTting the full `api_fields` payload back. So all API-returned fields (language, language_code, first_name, last_name, etc.) are also auto-synced — not just phone_number and extension. If the PUT fails, the attribute is reverted to its old value and a `PutError` is raised.
|
|
708
|
+
|
|
709
|
+
#### `copy_config(target_location, phone_number=None, passcode=None)`
|
|
710
|
+
|
|
711
|
+
```python
|
|
712
|
+
def copy_config(self,
|
|
713
|
+
target_location: wxcadm.Location,
|
|
714
|
+
phone_number: str = None,
|
|
715
|
+
passcode: str = None) -> bool
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
Copies the Voice Portal settings (language, extension, name) to another Calling-enabled location. Phone number and passcode are NOT copied unless explicitly provided.
|
|
719
|
+
|
|
720
|
+
Raises `ValueError` if the target location is not Webex Calling enabled.
|
|
721
|
+
|
|
722
|
+
---
|
|
723
|
+
|
|
724
|
+
### CallParkExtension
|
|
725
|
+
|
|
726
|
+
```python
|
|
727
|
+
@dataclass
|
|
728
|
+
class CallParkExtension:
|
|
729
|
+
location: wxcadm.Location
|
|
730
|
+
id: str
|
|
731
|
+
name: str
|
|
732
|
+
extension: str
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
Created via `loc.park_extensions` (property) or `loc.create_park_extension(name, extension)`.
|
|
736
|
+
|
|
737
|
+
#### `get_monitored_by()`
|
|
738
|
+
|
|
739
|
+
```python
|
|
740
|
+
def get_monitored_by(self) -> Optional[list]
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
Returns a list of users/workspaces monitoring this park extension. Uses the org-level `get_all_monitoring()` method.
|
|
744
|
+
|
|
745
|
+
---
|
|
746
|
+
|
|
747
|
+
### PagingGroup
|
|
748
|
+
|
|
749
|
+
```python
|
|
750
|
+
@dataclass
|
|
751
|
+
class PagingGroup:
|
|
752
|
+
location: wxcadm.Location
|
|
753
|
+
id: str
|
|
754
|
+
name: str
|
|
755
|
+
spark_id: str # auto-computed
|
|
756
|
+
config: dict # auto-populated on init
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
#### `refresh_config()`
|
|
760
|
+
|
|
761
|
+
```python
|
|
762
|
+
def refresh_config(self) -> None
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
Re-fetches the paging group configuration from `v1/telephony/config/locations/{loc_id}/paging/{id}`.
|
|
766
|
+
|
|
767
|
+
**Access pattern:** PagingGroup instances are accessed at the **org level** via `org.paging_groups` (a lazily-loaded list property that fetches from `v1/telephony/config/paging`) and `org.get_paging_group(id=, name=, spark_id=)`. They are NOT exposed as a Location property despite being location-scoped.
|
|
768
|
+
|
|
769
|
+
---
|
|
770
|
+
|
|
771
|
+
### OutgoingPermissionDigitPattern
|
|
772
|
+
|
|
773
|
+
Accessed via `loc.outgoing_permission_digit_patterns`.
|
|
774
|
+
|
|
775
|
+
#### OutgoingPermissionDigitPatternList
|
|
776
|
+
|
|
777
|
+
```python
|
|
778
|
+
class OutgoingPermissionDigitPatternList:
|
|
779
|
+
patterns: list[OutgoingPermissionDigitPattern]
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
Methods:
|
|
783
|
+
|
|
784
|
+
```python
|
|
785
|
+
def refresh(self) -> self
|
|
786
|
+
def create(self, name: str, pattern: str, action: str, transfer_enabled: Optional[bool] = False) -> OutgoingPermissionDigitPattern
|
|
787
|
+
def delete_all(self) -> bool
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
**Valid `action` values:** `'ALLOW'`, `'BLOCK'`, `'AUTH_CODE'`, `'TRANSFER_NUMBER_1'`, `'TRANSFER_NUMBER_2'`, `'TRANSFER_NUMBER_3'`
|
|
791
|
+
|
|
792
|
+
```python
|
|
793
|
+
patterns = loc.outgoing_permission_digit_patterns
|
|
794
|
+
new = patterns.create(name="Block 900", pattern="1900XXXXXXX", action="BLOCK")
|
|
795
|
+
patterns.delete_all() # remove all patterns at the location
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
#### OutgoingPermissionDigitPattern Instance
|
|
799
|
+
|
|
800
|
+
| Attribute | Type | Description |
|
|
801
|
+
|-----------|------|-------------|
|
|
802
|
+
| `id` | `str` | Pattern ID |
|
|
803
|
+
| `name` | `str` | Pattern name |
|
|
804
|
+
| `pattern` | `str` | The digit pattern |
|
|
805
|
+
| `action` | `str` | Action taken (ALLOW, BLOCK, etc.) |
|
|
806
|
+
| `transfer_enabled` | `bool` | Whether applied to transferred/forwarded calls |
|
|
807
|
+
|
|
808
|
+
```python
|
|
809
|
+
def update(self, name=None, pattern=None, action=None, transfer_enabled=None) -> OutgoingPermissionDigitPattern
|
|
810
|
+
def delete(self) -> bool
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
Only pass the values you want to change to `update()`.
|
|
814
|
+
|
|
815
|
+
---
|
|
816
|
+
|
|
817
|
+
### VoicemailGroup
|
|
818
|
+
|
|
819
|
+
Managed at the **org level** via `org.voicemail_groups` (a `VoicemailGroupList`), but scoped to a location.
|
|
820
|
+
|
|
821
|
+
#### VoicemailGroupList
|
|
822
|
+
|
|
823
|
+
```python
|
|
824
|
+
class VoicemailGroupList(UserList):
|
|
825
|
+
def __init__(self, org: wxcadm.Org)
|
|
826
|
+
```
|
|
827
|
+
|
|
828
|
+
Methods:
|
|
829
|
+
|
|
830
|
+
```python
|
|
831
|
+
def refresh(self) -> self
|
|
832
|
+
def get(self, name: str = None, id: str = None) -> Optional[VoicemailGroup]
|
|
833
|
+
def create(self,
|
|
834
|
+
location: wxcadm.Location,
|
|
835
|
+
name: str,
|
|
836
|
+
extension: str,
|
|
837
|
+
passcode: str,
|
|
838
|
+
phone_number: Optional[str] = None,
|
|
839
|
+
first_name: Optional[str] = None,
|
|
840
|
+
last_name: Optional[str] = None,
|
|
841
|
+
language_code: Optional[str] = 'en_us',
|
|
842
|
+
message_storage: Optional[dict] = None,
|
|
843
|
+
notifications: Optional[dict] = None,
|
|
844
|
+
fax_message: Optional[dict] = None,
|
|
845
|
+
transfer_to_number: Optional[dict] = None,
|
|
846
|
+
email_copy_of_message: Optional[dict] = None) -> VoicemailGroup
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
Default values for `create()` if not provided:
|
|
850
|
+
- `message_storage`: `{'storageType': 'INTERNAL'}`
|
|
851
|
+
- `notifications`, `fax_message`, `transfer_to_number`, `email_copy_of_message`: `{'enabled': False}`
|
|
852
|
+
|
|
853
|
+
#### VoicemailGroup Instance
|
|
854
|
+
|
|
855
|
+
Core attributes (available immediately):
|
|
856
|
+
|
|
857
|
+
| Attribute | Type | Description |
|
|
858
|
+
|-----------|------|-------------|
|
|
859
|
+
| `id` | `str` | Voicemail Group ID |
|
|
860
|
+
| `name` | `str` | Group name |
|
|
861
|
+
| `location_name` | `str` | Location name |
|
|
862
|
+
| `location_id` | `str` | Location ID |
|
|
863
|
+
| `extension` | `str` | Extension number |
|
|
864
|
+
| `enabled` | `bool` | Whether the group is enabled |
|
|
865
|
+
| `esn` | `Optional[str]` | ESN |
|
|
866
|
+
|
|
867
|
+
Lazy-loaded properties (trigger an API call on first access):
|
|
868
|
+
|
|
869
|
+
| Property | Type | Description |
|
|
870
|
+
|----------|------|-------------|
|
|
871
|
+
| `phone_number` | `str` | DID |
|
|
872
|
+
| `first_name` | `str` | Directory first name |
|
|
873
|
+
| `last_name` | `str` | Directory last name |
|
|
874
|
+
| `language_code` | `str` | Language code |
|
|
875
|
+
| `greeting_type` | `str` | `'DEFAULT'` or `'CUSTOM'` |
|
|
876
|
+
| `greeting_uploaded` | `bool` | Whether a custom greeting was uploaded |
|
|
877
|
+
| `greeting_description` | `str` | Custom greeting description |
|
|
878
|
+
| `message_storage` | `dict` | Storage config |
|
|
879
|
+
| `notifications` | `dict` | Notification settings |
|
|
880
|
+
| `fax_message` | `dict` | Fax settings |
|
|
881
|
+
| `transfer_to_number` | `dict` | Transfer settings |
|
|
882
|
+
| `email_copy_of_message` | `dict` | Email copy settings |
|
|
883
|
+
| `message_forwarding_enabled` | `bool` | Voice message forwarding status |
|
|
884
|
+
|
|
885
|
+
Methods:
|
|
886
|
+
|
|
887
|
+
```python
|
|
888
|
+
def update(self, name=None, phone_number=None, extension=None, first_name=None,
|
|
889
|
+
last_name=None, enabled=None, language_code=None, greeting_type=None,
|
|
890
|
+
greeting_description=None, message_storage=None, notifications=None,
|
|
891
|
+
fax_message=None, transfer_to_number=None, email_copy_of_message=None) -> VoicemailGroup
|
|
892
|
+
def delete(self) -> bool
|
|
893
|
+
def enable_email_copy(self, email: str) -> VoicemailGroup # shortcut for update()
|
|
894
|
+
```
|
|
895
|
+
|
|
896
|
+
---
|
|
897
|
+
|
|
898
|
+
## wxcadm vs wxc_sdk
|
|
899
|
+
|
|
900
|
+
### Location access patterns
|
|
901
|
+
|
|
902
|
+
| Operation | wxcadm | wxc_sdk |
|
|
903
|
+
|-----------|--------|---------|
|
|
904
|
+
| List locations | `org.locations` (auto-fetches) | `api.locations.list()` (returns generator) |
|
|
905
|
+
| Get by name | `org.locations.get(name="...")` | `api.locations.list(name="...")` then iterate |
|
|
906
|
+
| Get by ID | `org.locations.get(id="...")` | `api.locations.details(location_id="...")` |
|
|
907
|
+
| Create | `org.locations.create(...)` returns `Location` | `api.locations.create(...)` returns ID string |
|
|
908
|
+
| Delete | Not supported (returns `False`) | `api.locations.delete(location_id)` |
|
|
909
|
+
|
|
910
|
+
### Calling enablement
|
|
911
|
+
|
|
912
|
+
| Operation | wxcadm | wxc_sdk |
|
|
913
|
+
|-----------|--------|---------|
|
|
914
|
+
| Check if Calling-enabled | `loc.calling_enabled` (bool property) | Check via `api.telephony.location.details()` |
|
|
915
|
+
| Enable Calling | `loc.enable_webex_calling()` | `api.telephony.location.enable_for_calling(location)` |
|
|
916
|
+
| Filter Calling locations | `org.locations.webex_calling()` (bulk API) | Manual filtering required |
|
|
917
|
+
| Filter by PSTN | `org.locations.with_pstn()` / `without_pstn()` | Manual filtering required |
|
|
918
|
+
|
|
919
|
+
### Key architectural differences
|
|
920
|
+
|
|
921
|
+
1. **Caching**: wxcadm caches calling config, numbers, and feature lists as instance attributes. wxc_sdk generally does not cache and makes a fresh API call each time.
|
|
922
|
+
|
|
923
|
+
2. **Object model**: wxcadm uses a `Location` object with rich properties that lazily load sub-features (hunt groups, call queues, schedules, etc.). wxc_sdk uses separate API method groups (`api.telephony.callqueue`, `api.telephony.huntgroup`, etc.) that take a `location_id` parameter.
|
|
924
|
+
|
|
925
|
+
3. **List classes**: wxcadm wraps results in `UserList` subclasses (e.g., `LocationList`, `CallQueueList`) with `.get()` and `.refresh()` methods. wxc_sdk returns plain generators or lists.
|
|
926
|
+
|
|
927
|
+
4. **Setter pattern**: wxcadm uses separate `set_*` methods (e.g., `set_ecbn()`, `set_routing_prefix()`) rather than property setters that auto-push. The exception is `VoicePortal` which extends `RealtimeClass` for auto-push behavior.
|
|
928
|
+
|
|
929
|
+
5. **Schedule management**: wxcadm exposes `LocationSchedule` objects with `add_holiday()`, `create_event()`, `clone()`, etc. wxc_sdk uses `api.telephony.schedules` (a `ScheduleApi` instance) with `list()`, `details()`, `create()`, `update()`, `delete()`, and event-level methods.
|
|
930
|
+
|
|
931
|
+
6. **Bulk operations**: wxcadm's `LocationList.webex_calling()` uses a single bulk API call (`v1/telephony/config/locations`) for efficiency (added in v4.3.9). Earlier versions made per-location calls.
|
|
932
|
+
|
|
933
|
+
---
|
|
934
|
+
|
|
935
|
+
## See Also
|
|
936
|
+
|
|
937
|
+
- [provisioning.md](provisioning.md) — wxc_sdk location provisioning patterns (creation, calling enablement, number assignment)
|
|
938
|
+
- [location-calling-core.md](location-calling-core.md) — wxc_sdk location-level call settings (caller ID, voicemail, music on hold, outgoing permissions)
|