Source code for wxc_sdk.telephony.devices

"""
Telephony devices
"""
import json
from collections.abc import Generator
from typing import Optional, Union, Any

from pydantic import TypeAdapter, Field, field_validator, field_serializer

from ...api_child import ApiChild
from ...base import ApiModel, plus1, to_camel, enum_str
from ...base import SafeEnum as Enum

__all__ = ['DectDevice', 'MemberCommon', 'DeviceMember', 'DeviceMembersResponse', 'AvailableMember', 'MACState',
           'MACStatus', 'MACValidationResponse', 'TelephonyDevicesApi', 'LineKeyType', 'ProgrammableLineKey',
           'LineKeyTemplate', 'TelephonyDeviceDetails', 'ActivationState', 'TelephonyDeviceOwner',
           'TelephonyDeviceProxy', 'LayoutMode', 'KemModuleType', 'KemKey', 'DeviceLayout', 'DeviceSettings']

from ...common import PrimaryOrShared, UserType, ValidationStatus, DeviceCustomization, IdAndName, \
    ApplyLineKeyTemplateAction


[docs] class ActivationState(str, Enum): #: Indicates a device is activating using an activation code. activating = 'activating' #: Indicates a device has been activated using an activation code. activated = 'activated' #: Indicates a device has not been activated using an activation code. deactivated = 'deactivated'
[docs] class TelephonyDeviceOwner(ApiModel): #: Identifies a device endpoint in standalone mode or a SIP URI public identity in IMS mode. line_port: Optional[str] = None #: SIP authentication user name for the owner of the device. sip_user_name: Optional[str] = None
[docs] class TelephonyDeviceProxy(ApiModel): #: Outgoing server which the phone should use for all SIP requests. Not set if the response has no body. outbound_proxy: Optional[str] = None
[docs] class TelephonyDeviceDetails(ApiModel): #: Manufacturer of the device. manufacturer: Optional[str] = None owner: Optional[TelephonyDeviceOwner] = None proxy: Optional[TelephonyDeviceProxy] = None #: Device manager(s). managed_by: Optional[str] = None #: A unique identifier for the device. id: Optional[str] = None #: The current IP address of the device. ip: Optional[str] = None #: The unique address for the network adapter. mac: Optional[str] = None #: A model type of the device. model: Optional[str] = None #: Activation state of the device. This field is only populated for a device added by a unique activation code #: generated by Control Hub for use with Webex. activation_state: Optional[ActivationState] = None #: Comma-separated array of tags used to describe the device. description: Optional[list[str]] = None #: Enabled / disabled status of the upgrade channel. upgrade_channel_enabled: Optional[bool] = None
[docs] class DectDevice(ApiModel): #: Model name of the device. model: str #: Display name of the device. display_name: str #: Indicates number of base stations. number_of_base_stations: int #: Indicates number of port lines, number_of_line_ports: int #: Indicates number of supported registrations. number_of_registrations_supported: int
[docs] class MemberCommon(ApiModel): #: Unique identifier for the member. member_id: str = Field(alias='id') member_type: UserType = Field(default=UserType.people) #: First name of a person or workspace. first_name: Optional[str] = None #: Last name of a person or workspace. last_name: Optional[str] = None #: Phone Number of a person or workspace. In some regions phone numbers are not returned in E.164 format. This #: will be supported in a future update. phone_number: Optional[str] = None #: Extension of a person or workspace. extension: Optional[str] = None #: Routing prefix of location. routingPrefix: Optional[str] = None #: Routing prefix + extension of a person or workspace. esn: Optional[str] = None #: T.38 Fax Compression setting and is available only for ATA Devices. Choose T.38 fax compression if the device #: requires this option. This will override user level compression options. t38_fax_compression_enabled: Optional[bool] = None #: Line type is used to differentiate Primary and SCA, at which endpoint it is assigned. line_type: PrimaryOrShared = Field(default=PrimaryOrShared.primary) #: Set how a person's device behaves when a call is declined. When set to true, a call decline request is extended #: to all the endpoints on the device. When set to false, a call decline request only declines the current endpoint. allow_call_decline_enabled: Optional[bool] = Field(default=True) location: Optional[IdAndName] = None @field_validator('phone_number', mode='before') def e164(cls, v): """ :meta private: """ return plus1(v)
[docs] class DeviceMember(MemberCommon): #: This field indicates whether the person or the workspace is the owner of the device, and points to a primary #: Line/Port of the device. primary_owner: bool = Field(default=False) #: Port number assigned to person or workspace. port: int = Field(default=1) #: Number of lines that have been configured for the person on the device. Can only be larger than one for primary #: owner line_weight: int = Field(default=1) #: Device line label. line_label: Optional[str] = None #: Registration Host IP address for the line port. host_ip: Optional[str] = Field(alias='hostIP', default=None) #: Registration Remote IP address for the line port. remote_ip: Optional[str] = Field(alias='remoteIP', default=None) #: Enable Hotline. Configure this line to automatically call a predefined number whenever taken off-hook. Once #: enabled, the line can only make calls to the predefined number set in hotlineDestination. hotline_enabled: bool = Field(default=False) #: The preconfigured number for Hotline. Required only if hotlineEnabled is set to true. hotline_destination: Optional[str] = None
[docs] @staticmethod def from_available(available: 'AvailableMember') -> 'DeviceMember': data = json.loads(available.model_dump_json()) return DeviceMember.model_validate(data)
[docs] class DeviceMembersResponse(ApiModel): """ Get Device Members response """ model: str members: list[DeviceMember] max_line_count: int # assert that members are always sorted by port number @field_validator('members', mode='after') def sort_members(cls, v): """ :meta private: """ v.sort(key=lambda dm: dm.port) return v
[docs] class AvailableMember(MemberCommon): ...
[docs] class MACState(str, Enum): """ State of the MAC address. """ #: The requested MAC address is available. available = 'AVAILABLE' #: The requested MAC address is unavailable. unavailable = 'UNAVAILABLE' #: The requested MAC address is duplicated. duplicate_in_list = 'DUPLICATE_IN_LIST' #: The requested MAC address is invalid. invalid = 'INVALID'
[docs] class MACStatus(ApiModel): #: MAC address. mac: str #: State of the MAC address. state: MACState #: MAC address validation error code. error_code: Optional[int] = None #: Provides a status message about the MAC address. message: Optional[str] = None
[docs] class MACValidationResponse(ApiModel): #: Status of MAC address. status: ValidationStatus #: Contains an array of all the MAC address provided and their statuses. mac_status: Optional[list[MACStatus]] = None
[docs] class LineKeyType(str, Enum): #: PRIMARY_LINE is the user's primary extension. This is the default assignment for Line Key Index 1 and cannot be #: modified. primary_line = 'PRIMARY_LINE' #: Shows the appearance of other users on the owner's phone. shared_line = 'SHARED_LINE' #: Enables User and Call Park monitoring. monitor = 'MONITOR' #: Allows users to reach a telephone number, extension or a SIP URI. speed_dial = 'SPEED_DIAL' #: An open key will automatically take the configuration of a monitor button starting with the first open key. #: These buttons are also usable by the user to configure speed dial numbers on these keys. open = 'OPEN' #: Button not usable but reserved for future features. closed = 'CLOSED'
[docs] class ProgrammableLineKey(ApiModel): #: An index representing a Line Key. Index starts from 1 representing the first key on the left side of the phone. #: example: 2 line_key_index: Optional[int] = None #: The action that would be performed when the Line Key is pressed. #: example: SPEED_DIAL line_key_type: Optional[LineKeyType] = None #: This is applicable only when the lineKeyType is `SPEED_DIAL`. #: example: Help Line line_key_label: Optional[str] = None #: This is applicable only when the lineKeyType is `SPEED_DIAL` and the value must be a valid Telephone Number, #: Ext, or SIP URI (format: user@host using A-Z,a-z,0-9,-_ .+ for user and host). #: example: 5646 line_key_value: Optional[str] = None
[docs] @classmethod def standard_plk_list(cls, lines: int = 10) -> list['ProgrammableLineKey']: """ get a standard list of programmable line keys of given length. 1st line key is primary line and all other are "open" :param lines: number of programmable line keys :return: list of programmable line keys """ r = [ProgrammableLineKey(line_key_index=i, line_key_type=LineKeyType.open) for i in range(1, lines + 1)] r[0].line_key_type = LineKeyType.primary_line return r
[docs] class LineKeyTemplate(ApiModel): #: Unique identifier for the Line Key Template #: example: Y2lzY29zcGFyazovL1VTL0RFVklDRV9MSU5FX0tFWV9URU1QTEFURS9kNDUzM2MwYi1hZGRmLTRjODUtODk0YS1hZTVkOTAyYzAyMDM= id: Optional[str] = None #: Name of the Line Key Template #: example: template for 8845 template_name: Optional[str] = None #: The Device Model for which the Line Key Template is applicable #: example: DMS Cisco 8845 device_model: Optional[str] = None #: The friendly display name used to represent the device model in Control Hub #: example: Cisco 8845 display_name: Optional[str] = Field(alias='modelDisplayName', default=None) #: Indicates whether user can reorder the line keys. user_reorder_enabled: Optional[bool] = None #: Contains a mapping of Line Keys and their corresponding actions. line_keys: Optional[list[ProgrammableLineKey]] = None def create_or_update(self) -> dict[str, Any]: """ dict for create or update :meta private: """ return self.model_dump(mode='json', exclude_none=True, by_alias=True, exclude={'id', 'display_name'})
[docs] class LayoutMode(str, Enum): #: Default layout mode when a new device is added. default = 'DEFAULT' #: Enables a device to have its custom layout. custom = 'CUSTOM'
[docs] class KemModuleType(str, Enum): #: Extension module has 14 line keys that can be configured. kem_14_keys = 'KEM_14_KEYS' #: Extension module has 18 line keys that can be configured. kem_18_keys = 'KEM_18_KEYS' #: Extension module has 20 line keys that can be configured. kem_20_keys = 'KEM_20_KEYS'
[docs] class KemKey(ApiModel): #: An index representing a KEM Module. The Index starts from 1 representing the first KEM Module. #: example: 1 kem_module_index: Optional[int] = None #: An index representing a KEM Key. The Index starts from 1 representing the first key on the left side of the #: phone. #: example: 1 kem_key_index: Optional[int] = None #: The action that would be performed when the KEM Key is pressed. #: example: SPEED_DIAL kem_key_type: Optional[LineKeyType] = None #: Applicable only when the kemKeyType is `SPEED_DIAL`. #: example: Office kem_key_label: Optional[str] = None #: Applicable only when the kemKeyType is `SPEED_DIAL`. Value must be a valid Telephone Number, Ext, or SIP URI #: (format: `user@host` limited to `A-Z,a-z,0-9,-_ .+` for user and host). #: example: 213457 kem_key_value: Optional[str] = None
[docs] class DeviceLayout(ApiModel): #: Defines the layout mode of the device, i.e. DEFAULT or CUSTOM. #: example: CUSTOM layout_mode: Optional[LayoutMode] = None #: If `true`, user customization is enabled.. #: example: True user_reorder_enabled: Optional[bool] = None #: Contains a mapping of Line Keys and their corresponding actions. line_keys: Optional[list[ProgrammableLineKey]] = None #: Type of KEM module. #: example: KEM_14_KEYS kem_module_type: Optional[KemModuleType] = None #: Contains a mapping of KEM Keys and their corresponding actions. kem_keys: Optional[list[KemKey]] = None
[docs] def update(self) -> dict: """ get data for update :meta private: """ return self.model_dump(mode='json', exclude_none=True, by_alias=True)
[docs] class DeviceSettings(ApiModel): #: True -> Minimize data use during compression. #: #: False -> Ignore data use during compression. compression: Optional[bool] = None @field_serializer('compression') def ser_compression(self, v: bool) -> str: """ :meta private: """ return 'ON' if v else 'OFF'
[docs] class TelephonyDevicesApi(ApiChild, base='telephony/config'): """ Telephony devices API """
[docs] def details(self, device_id: str, org_id: str = None) -> TelephonyDeviceDetails: """ Get Webex Calling Device Details Retrieves Webex Calling device details that include information needed for third-party device management. Webex calling devices are associated with a specific user Workspace or Virtual Line. Webex Calling devices share the location with the entity that owns them. This API requires a full, location, user, or read-only admin auth token with the scope of `spark-admin:telephony_config_read`. :param device_id: Unique identifier for the device. :type device_id: str :param org_id: ID of the organization in which the device resides. :type org_id: str :rtype: :class:`TelephonyDeviceDetails` """ params = {} if org_id is not None: params['orgId'] = org_id url = self.ep(f'devices/{device_id}') data = super().get(url, params=params) r = TelephonyDeviceDetails.model_validate(data) return r
[docs] def members(self, device_id: str, org_id: str = None) -> DeviceMembersResponse: """ Get Device Members Get the list of all the members of the device including primary and secondary users. A device member can be either a person or a workspace. An admin can access the list of member details, modify member details and search for available members on a device. Retrieving this list requires a full or read-only administrator auth token with a scope of spark-admin:telephony_config_read. :param device_id: Unique identifier for the device. :type device_id: str :param org_id: Retrieves the list of all members of the device in this Organization. :type org_id: str :return: Device model, line count, and members :rtype: DeviceMembersResponse """ params = org_id and {'orgId': org_id} or None url = self.ep(f'devices/{device_id}/members') data = self.get(url=url, params=params) return DeviceMembersResponse.model_validate(data)
[docs] def update_members(self, device_id: str, members: Optional[list[Union[DeviceMember, AvailableMember]]], org_id: str = None): """ Modify member details on the device. A device member can be either a person or a workspace. An admin can access the list of member details, modify member details and search for available members on a device. Modifying members on the device requires a full administrator auth token with a scope of spark-admin:telephony_config_write. :param device_id: Unique identifier for the device. :type device_id: str :param members: New member details for the device. If the member's list is missing then all the users are removed except the primary user. :type members: list[Union[DeviceMember, AvailableMember] :param org_id: Modify members on the device in this organization. :type org_id: str """ members_for_update = [] for member in members: if isinstance(member, AvailableMember): member = DeviceMember.from_available(member) else: member = member.model_copy(deep=True) members_for_update.append(member) if members_for_update: # now assign port indices port = 1 for member in members_for_update: member.port = port port += member.line_weight # create body if members_for_update: members = ','.join(m.model_dump_json(include={'member_id', 'port', 't38_fax_compression_enabled', 'primary_owner', 'line_type', 'line_weight', 'line_label', 'hotline_enabled', 'hotline_destination', 'allow_call_decline_enabled'}) for m in members_for_update) body = f'{{"members": [{members}]}}' else: body = None url = self.ep(f'devices/{device_id}/members') params = org_id and {'orgId': org_id} or None self.put(url=url, data=body, params=params)
[docs] def available_members(self, device_id: str, location_id: str = None, member_name: str = None, phone_number: str = None, extension: str = None, org_id: str = None, **params) -> Generator[AvailableMember, None, None]: """ Search members that can be assigned to the device. A device member can be either a person or a workspace. A admin can access the list of member details, modify member details and search for available members on a device. This requires a full or read-only administrator auth token with a scope of spark-admin:telephony_config_read. :param device_id: Unique identifier for the device. :type device_id: str :param location_id: Search (Contains) based on number. :type location_id: str :param member_name: Search (Contains) numbers based on member name. :type member_name: str :param phone_number: Search (Contains) based on number. :type phone_number: str :param extension: Search (Contains) based on extension. :type extension: str :param org_id: Retrieves the list of available members on the device in this Organization. :type org_id: str :return: list of available members """ params.update((to_camel(p), v) for p, v in locals().items() if p not in {'self', 'params', 'device_id'} and v is not None) url = self.ep(f'devices/{device_id}/availableMembers') # noinspection PyTypeChecker return self.session.follow_pagination(url=url, model=AvailableMember, params=params, item_key='members')
[docs] def apply_changes(self, device_id: str, org_id: str = None): """ Apply Changes for a specific device Issues request to the device to download and apply changes to the configuration. Applying changes for a specific device requires a full administrator auth token with a scope of spark-admin:telephony_config_write. :param device_id: Unique identifier for the device. :type device_id: str :param org_id: Apply changes for a device in this Organization. :type org_id: str """ params = org_id and {'orgId': org_id} or None url = self.ep(f'devices/{device_id}/actions/applyChanges/invoke') self.post(url=url, params=params)
[docs] def device_settings(self, device_id: str, device_model: str, org_id: str = None) -> DeviceCustomization: """ Get override settings for a device. Device settings lists all the applicable settings for an MPP and an ATA devices at the device level. An admin can also modify the settings. DECT devices do not support settings at the device level. This requires a full or read-only administrator auth token with a scope of spark-admin:telephony_config_read. :param device_id: Unique identifier for the device. :type device_id: str :param device_model: Model type of the device. :type device_model: str :param org_id: Settings on the device in this organization. :type org_id: str :return: Device settings :rtype: DeviceCustomization """ params = {'model': device_model} if org_id: params['orgId'] = org_id url = self.ep(f'devices/{device_id}/settings') data = self.get(url=url, params=params) return DeviceCustomization.model_validate(data)
[docs] def update_device_settings(self, device_id: str, device_model: str, customization: DeviceCustomization, org_id: str = None): """ Modify override settings for a device. Device settings list all the applicable settings for an MPP and an ATA devices at the device level. Admins can also modify the settings. NOTE: DECT devices do not support settings at the device level. Updating settings on the device requires a full administrator auth token with a scope of spark-admin:telephony_config_write. :param device_id: Unique identifier for the device. :type device_id: str :param device_model: Device model name. :type device_model: str :param customization: Indicates the customization object of the device settings. :type customization: DeviceCustomization :param org_id: Organization in which the device resides.. :type org_id: str Example : .. code-block:: python # target_device is a TelephonyDevice object target_device: TelephonyDevice # get device level settings settings = api.telephony.devices.device_settings(device_id=target_device.device_id, device_model=target_device.model) # update settings (display name format) and enable device level customization settings.customizations.mpp.display_name_format = DisplayNameSelection.person_last_then_first_name settings.custom_enabled = True # update the device level settings api.telephony.devices.update_device_settings(device_id=target_device.device_id, device_model=target_device.model, customization=settings) # apply changes to device api.telephony.devices.apply_changes(device_id=target_device.device_id) """ params = {'model': device_model} if org_id: params['orgId'] = org_id url = self.ep(f'devices/{device_id}/settings') body = customization.model_dump_json(include={'customizations', 'custom_enabled'}) self.put(url=url, params=params, data=body)
[docs] def dect_devices(self, org_id: str = None) -> list[DectDevice]: """ Read the DECT device type list Get DECT device type list with base stations and line ports supported count. This is a static list. Retrieving this list requires a full or read-only administrator auth token with a scope of spark-admin:telephony_config_read. :param org_id: :return: """ params = org_id and {'orgId': org_id} or None url = self.ep('devices/dects/supportedDevices') data = self.get(url=url, params=params) return TypeAdapter(list[DectDevice]).validate_python(data['devices'])
[docs] def validate_macs(self, macs: list[str], org_id: str = None) -> MACValidationResponse: """ Validate a list of MAC addresses. Validating this list requires a full or read-only administrator auth token with a scope of spark-admin:telephony_config_write. :param macs: MAC addresses to be validated. :type macs: list[str] :param org_id: Validate the mac address(es) for this organization. :type org_id: str :return: validation response :rtype: :class:`MACValidationResponse` """ params = org_id and {'orgId': org_id} or None url = self.ep('devices/actions/validateMacs/invoke') data = self.post(url=url, params=params, json={'macs': macs}) return MACValidationResponse.model_validate(data)
[docs] def create_line_key_template(self, template: LineKeyTemplate, org_id: str = None) -> str: """ Create a Line Key Template Create a Line Key Template in this organization. Line Keys also known as Programmable Line Keys (PLK) are the keys found on either sides of a typical desk phone display. A Line Key Template is a definition of actions that will be performed by each of the Line Keys for a particular device model. This API allows customers to create a Line Key Template for a device model. Creating a Line Key Template requires a full administrator auth token with a scope of `spark-admin:telephony_config_write`. :param template: Line key template to create :type template: LineKeyTemplate :param org_id: id of organization to create the line key template in :type org_id: str :return: id of new line key template :rtype: str """ params = {} if org_id is not None: params['orgId'] = org_id body = template.create_or_update() url = self.ep('devices/lineKeyTemplates') data = super().post(url, params=params, json=body) r = data['id'] return r
[docs] def list_line_key_templates(self, org_id: str = None) -> list[LineKeyTemplate]: """ Read the list of Line Key Templates List all Line Key Templates available for this organization. Line Keys also known as Programmable Line Keys (PLK) are the keys found on either sides of a typical desk phone display. A Line Key Template is a definition of actions that will be performed by each of the Line Keys for a particular device model. This API allows users to retrieve the list of Line Key Templates that are available for the organization. Retrieving this list requires a full, user or read-only administrator or location administrator auth token with a scope of `spark-admin:telephony_config_read`. :param org_id: List line key templates for this organization. :type org_id: str :rtype: list[LineKeyTemplate] """ params = {} if org_id is not None: params['orgId'] = org_id url = self.ep('devices/lineKeyTemplates') data = super().get(url, params=params) r = TypeAdapter(list[LineKeyTemplate]).validate_python(data['lineKeyTemplates']) return r
[docs] def line_key_template_details(self, template_id: str, org_id: str = None) -> LineKeyTemplate: """ Get details of a Line Key Template Get detailed information about a Line Key Template by template ID in an organization. Line Keys also known as Programmable Line Keys (PLK) are the keys found on either sides of a typical desk phone display. A Line Key Template is a definition of actions that will be performed by each of the Line Keys for a particular device model. This API allows users to retrieve a line key template by its ID in an organization. Retrieving a line key template requires a full, user or read-only administrator auth token with a scope of `spark-admin:telephony_config_read`. :param template_id: Get line key template for this template ID. :type template_id: str :param org_id: Retrieve a line key template for this organization. :type org_id: str :rtype: :class:`GetLineKeyTemplateResponse` """ params = {} if org_id is not None: params['orgId'] = org_id url = self.ep(f'devices/lineKeyTemplates/{template_id}') data = super().get(url, params=params) r = LineKeyTemplate.model_validate(data) return r
[docs] def modify_line_key_template(self, template: LineKeyTemplate, org_id: str = None): """ Modify a Line Key Template Modify a line key template by its template ID in an organization. Line Keys also known as Programmable Line Keys (PLK) are the keys found on either sides of a typical desk phone display. A Line Key Template is a definition of actions that will be performed by each of the Line Keys for a particular device model. This API allows users to modify an existing Line Key Template by its ID in an organization. Modifying an existing line key template requires a full administrator auth token with a scope of `spark-admin:telephony_config_write`. :param template: new line key template settings :type template: LineKeyTemplate :param org_id: Modify a line key template for this organization. :type org_id: str """ params = {} if org_id is not None: params['orgId'] = org_id url = self.ep(f'devices/lineKeyTemplates/{template.id}') super().put(url, params=params, json=template.create_or_update())
[docs] def delete_line_key_template(self, template_id: str, org_id: str = None): """ Delete a Line Key Template Delete a Line Key Template by its template ID in an organization. Line Keys also known as Programmable Line Keys (PLK) are the keys found on either sides of a typical desk phone display. A Line Key Template is a definition of actions that will be performed by each of the Line Keys for a particular device model. This API allows users to delete an existing Line Key Templates by its ID in an organization. Deleting an existing line key template requires a full administrator auth token with a scope of `spark-admin:telephony_config_write`. :param template_id: Delete line key template with this template ID. :type template_id: str :param org_id: Delete a line key template for this organization. :type org_id: str :rtype: None """ params = {} if org_id is not None: params['orgId'] = org_id url = self.ep(f'devices/lineKeyTemplates/{template_id}') super().delete(url, params=params)
[docs] def preview_apply_line_key_template(self, action: ApplyLineKeyTemplateAction, template_id: str = None, location_ids: list[str] = None, exclude_devices_with_custom_layout: bool = None, include_device_tags: list[str] = None, exclude_device_tags: list[str] = None, more_shared_appearances_enabled: bool = None, few_shared_appearances_enabled: bool = None, more_monitor_appearances_enabled: bool = None, org_id: str = None) -> int: """ Preview Apply Line Key Template Preview the number of devices that will be affected by the application of a Line Key Template or when resetting devices to their factory Line Key settings. Line Keys also known as Programmable Line Keys (PLK) are the keys found on either sides of a typical desk phone display. A Line Key Template is a definition of actions that will be performed by each of the Line Keys for a particular device model. This API allows users to preview the number of devices that will be affected if a customer were to apply a Line Key Template or apply factory default Line Key settings to devices. Retrieving the number of devices affected requires a full administrator auth token with a scope of `spark-admin:telephony_config_write`. :param action: Line key Template action to perform. :type action: ApplyLineKeyTemplateAction :param template_id: `templateId` is required for `APPLY_TEMPLATE` action. :type template_id: str :param location_ids: Used to search for devices only in the given locations. :type location_ids: list[str] :param exclude_devices_with_custom_layout: Indicates whether to exclude devices with custom layout. :type exclude_devices_with_custom_layout: bool :param include_device_tags: Include devices only with these tags. :type include_device_tags: list[str] :param exclude_device_tags: Exclude devices with these tags. :type exclude_device_tags: list[str] :param more_shared_appearances_enabled: Refine search by warnings for More shared appearances than shared users. :type more_shared_appearances_enabled: bool :param few_shared_appearances_enabled: Refine search by warnings for Fewer shared appearances than shared users. :type few_shared_appearances_enabled: bool :param more_monitor_appearances_enabled: Refine search by warnings for more monitor appearances than monitors. :type more_monitor_appearances_enabled: bool :param org_id: Preview Line Key Template for this organization. :type org_id: str :rtype: int """ params = {} if org_id is not None: params['orgId'] = org_id body = dict() body['action'] = enum_str(action) if template_id is not None: body['templateId'] = template_id if location_ids is not None: body['locationIds'] = location_ids if exclude_devices_with_custom_layout is not None: body['excludeDevicesWithCustomLayout'] = exclude_devices_with_custom_layout if include_device_tags is not None: body['includeDeviceTags'] = include_device_tags if exclude_device_tags is not None: body['excludeDeviceTags'] = exclude_device_tags if more_shared_appearances_enabled is not None: body['moreSharedAppearancesEnabled'] = more_shared_appearances_enabled if few_shared_appearances_enabled is not None: body['fewSharedAppearancesEnabled'] = few_shared_appearances_enabled if more_monitor_appearances_enabled is not None: body['moreMonitorAppearancesEnabled'] = more_monitor_appearances_enabled url = self.ep('devices/actions/previewApplyLineKeyTemplate/invoke') data = super().post(url, params=params, json=body) r = data['deviceCount'] return r
[docs] def get_device_layout(self, device_id: str, org_id: str = None) -> DeviceLayout: """ Get Device Layout by Device ID Get layout information of a device by device ID in an organization. Device layout customizes a user’s programmable line keys (PLK) on the phone and any attached Key Expansion Modules (KEM) with the existing configured line members and the user’s monitoring list. This API requires a full or location administrator auth token with a scope of `spark-admin:telephony_config_read`. :param device_id: Get device layout for this device ID. :type device_id: str :param org_id: Retrieve a device layout for the device in this organization. :type org_id: str :rtype: :class:`DeviceLayout` """ params = {} if org_id is not None: params['orgId'] = org_id url = self.ep(f'devices/{device_id}/layout') data = super().get(url, params=params) r = DeviceLayout.model_validate(data) return r
[docs] def modify_device_layout(self, device_id: str, layout: DeviceLayout, org_id: str = None): """ Modify Device Layout by Device ID Modify the layout of a device by device ID in an organization. Device layout customizes a user’s programmable line keys (PLK) on the phone and any attached Key Expansion Modules (KEM) with the existing configured line members and the user’s monitoring list. This API requires a full or location administrator auth token with a scope of `spark-admin:telephony_config_write`. :param device_id: Modify device layout for this device ID. :type device_id: str :param layout: New layout :param org_id: Modify a device layout for the device in this organization. :type org_id: str :rtype: None """ params = {} if org_id is not None: params['orgId'] = org_id body = layout.update() url = self.ep(f'devices/{device_id}/layout') super().put(url, params=params, json=body)
[docs] def get_person_device_settings(self, person_id: str, org_id: str = None) -> DeviceSettings: """ Get Device Settings for a Person Device settings list the compression settings for a person. Device settings customize a device's behavior and performance. The compression field optimizes call quality for inbound and outbound calls. This API requires a full, location, user, or read-only administrator auth token with a scope of `spark-admin:telephony_config_read`. :param person_id: ID of the person to retrieve device settings. :type person_id: str :param org_id: Retrieves the device settings for a person in this organization. :type org_id: str :rtype: Compression """ params = {} if org_id is not None: params['orgId'] = org_id url = self.ep(f'people/{person_id}/devices/settings') data = super().get(url, params=params) r = DeviceSettings.model_validate(data) return r
[docs] def update_person_device_settings(self, person_id: str, settings: DeviceSettings, org_id: str = None): """ Update Device Settings for a Person Update device settings modifies the compression settings for a person. Device settings customize a device's behavior and performance. The compression field optimizes call quality for inbound and outbound calls. This API requires a full, location, or user administrator auth token with a scope of `spark-admin:telephony_config_write`. :param person_id: ID of the person to update device settings. :type person_id: str :param settings: New device settings :type settings: DeviceSettings :param org_id: Modify device settings for a person in this organization. :type org_id: str :rtype: None """ params = {} if org_id is not None: params['orgId'] = org_id body = settings.model_dump(mode='json', exclude_none=True, by_alias=True) url = self.ep(f'people/{person_id}/devices/settings') super().put(url, params=params, json=body)
[docs] def get_workspace_device_settings(self, workspace_id: str, org_id: str = None) -> DeviceSettings: """ Get Device Settings for a Workspace Device settings list the compression settings for a workspace. Device settings customize a device's behavior and performance. The compression field optimizes call quality for inbound and outbound calls. This API requires a full, location, user, or read-only administrator auth token with a scope of `spark-admin:telephony_config_read`. :param workspace_id: ID of the workspace for which to retrieve device settings. :type workspace_id: str :param org_id: Retrieves the device settings for a workspace in this organization. :type org_id: str :rtype: Compression """ params = {} if org_id is not None: params['orgId'] = org_id url = self.ep(f'workspaces/{workspace_id}/devices/settings') data = super().get(url, params=params) r = DeviceSettings.model_validate(data) return r
[docs] def update_workspace_device_settings(self, workspace_id: str, settings: DeviceSettings, org_id: str = None): """ Update Device Settings for a Workspace Update device settings modifies the compression settings for a workspace. Device settings customize a device's behavior and performance. The compression field optimizes call quality for inbound and outbound calls. This API requires a full, location, or user administrator auth token with a scope of `spark-admin:telephony_config_write`. :param workspace_id: ID of the workspace for which to update device settings. :type workspace_id: str :param settings: New device settings :type settings: DeviceSettings :param org_id: Modify the device settings for a workspace in this organization. :type org_id: str :rtype: None """ params = {} if org_id is not None: params['orgId'] = org_id body = settings.model_dump(mode='json', exclude_none=True, by_alias=True) url = self.ep(f'workspaces/{workspace_id}/devices/settings') super().put(url, params=params, json=body)