from collections.abc import Generator
from dataclasses import dataclass
from typing import Optional
from pydantic import TypeAdapter
from ...api_child import ApiChild
from ...base import ApiModel
from ...common import PrimaryOrShared, AssignedDectNetwork, UserNumber
from ...locations import LocationAddress
from ...person_settings import TelephonyDevice, AvailableNumbersApi
from ...person_settings.agent_caller_id import AgentCallerIdApi
from ...person_settings.barge import BargeApi
from ...person_settings.call_intercept import CallInterceptApi
from ...person_settings.call_recording import CallRecordingApi
from ...person_settings.call_waiting import CallWaitingApi
from ...person_settings.callbridge import CallBridgeApi
from ...person_settings.caller_id import ExternalCallerIdNamePolicy, CallerIdApi
from ...person_settings.common import ApiSelector
from ...person_settings.ecbn import ECBNApi
from ...person_settings.forwarding import PersonForwardingApi
from ...person_settings.moh import MusicOnHoldApi
from ...person_settings.permissions_in import IncomingPermissionsApi
from ...person_settings.permissions_out import OutgoingPermissionsApi
from ...person_settings.privacy import PrivacyApi
from ...person_settings.push_to_talk import PushToTalkApi
from ...person_settings.voicemail import VoicemailApi
__all__ = ['VirtualLine', 'VirtualLinesApi', 'VirtualLineLocation', 'VirtualLineNumberPhoneNumber',
'VirtualLineDevices']
[docs]
class VirtualLineLocation(ApiModel):
#: ID of location associated with virtual line.
id: Optional[str] = None
#: Name of location associated with virtual line.
name: Optional[str] = None
#: The address of the virtual line.
address: Optional[LocationAddress] = None
[docs]
class VirtualLine(ApiModel):
#: A unique identifier for the virtual line.
id: Optional[str] = None
#: Last name for virtual line.
last_name: Optional[str] = None
#: First name for virtual line.
first_name: Optional[str] = None
#: Display name defined for a virtual line.
display_name: Optional[str] = None
#: `callerIdLastName` for virtual line.
caller_id_last_name: Optional[str] = None
#: `callerIdFirstName` for virtual line.
caller_id_first_name: Optional[str] = None
#: `callerIdNumber` for virtual line.
caller_id_number: Optional[str] = None
#: `externalCallerIdNamePolicy` for the virtual line.
external_caller_id_name_policy: Optional[ExternalCallerIdNamePolicy] = None
#: `customExternalCallerIdName` for virtual line.
custom_external_caller_id_name: Optional[str] = None
#: Calling details of virtual line.
number: Optional[UserNumber] = None
#: Location details of virtual line.
location: Optional[VirtualLineLocation] = None
#: Number of devices assigned to a virtual line.
number_of_devices_assigned: Optional[int] = None
#: Type of billing plan.
billing_plan: Optional[str] = None
#: Flag to indicate a directory search.
directory_search_enabled: Optional[bool] = None
#: Virtual Line's announcement language.
announcement_language: Optional[str] = None
#: Time zone defined for the virtual line.
time_zone: Optional[str] = None
#: Calling details of virtual line.
#: List of devices assigned to a virtual line.
devices: Optional[list[TelephonyDevice]] = None
[docs]
class VirtualLineNumberPhoneNumber(ApiModel):
#: Phone number that is assigned to a virtual line.
direct_number: Optional[str] = None
#: Extension that is assigned to a virtual line.
extension: Optional[str] = None
#: If `true` marks the phone number as primary.
primary: Optional[bool] = None
[docs]
class VirtualLineDevices(ApiModel):
#: List of devices assigned to a virtual line.
devices: Optional[list[TelephonyDevice]] = None
#: Indicates to which line a device can be assigned.
available_endpoint_type: Optional[PrimaryOrShared] = None
#: Maximum number of devices a virtual line can be assigned to.
max_device_count: Optional[int] = None
[docs]
@dataclass(init=False, repr=False)
class VirtualLinesApi(ApiChild, base='telephony/config/virtualLines'):
#: agent caller id Api
agent_caller_id: AgentCallerIdApi
#: Available numbers for a virtual line
available_numbers: AvailableNumbersApi
#: barge settings
barge: BargeApi
#: Call bridge settings
call_bridge: CallBridgeApi
#: call intercept settings
call_intercept: CallInterceptApi
#: call recording settings
call_recording: CallRecordingApi
#: call waiting settings
call_waiting: CallWaitingApi
#: caller id settings
caller_id: CallerIdApi
#: ECBN settings
ecbn: ECBNApi
#: forwarding settings
forwarding: PersonForwardingApi
#: music on hold settings
music_on_hold: MusicOnHoldApi
#: incoming permissions
permissions_in: IncomingPermissionsApi
#: outgoing permissions
permissions_out: OutgoingPermissionsApi
#: Privacy Settings
privacy: PrivacyApi
#: Push to Talk Settings
push_to_talk: PushToTalkApi
#: Voicemail Settings
voicemail: VoicemailApi
[docs]
def __init__(self, session):
super().__init__(session=session)
self.agent_caller_id = AgentCallerIdApi(session=session, selector=ApiSelector.virtual_line)
self.available_numbers = AvailableNumbersApi(session=session, selector=ApiSelector.virtual_line)
self.barge = BargeApi(session=session, selector=ApiSelector.virtual_line)
self.call_bridge = CallBridgeApi(session=session, selector=ApiSelector.virtual_line)
self.call_intercept = CallInterceptApi(session=session, selector=ApiSelector.virtual_line)
self.call_recording = CallRecordingApi(session=session, selector=ApiSelector.virtual_line)
self.call_waiting = CallWaitingApi(session=session, selector=ApiSelector.virtual_line)
self.caller_id = CallerIdApi(session=session, selector=ApiSelector.virtual_line)
self.ecbn = ECBNApi(session=session, selector=ApiSelector.virtual_line)
self.forwarding = PersonForwardingApi(session=session, selector=ApiSelector.virtual_line)
self.music_on_hold = MusicOnHoldApi(session=session, selector=ApiSelector.virtual_line)
self.permissions_in = IncomingPermissionsApi(session=session, selector=ApiSelector.virtual_line)
self.permissions_out = OutgoingPermissionsApi(session=session, selector=ApiSelector.virtual_line)
self.privacy = PrivacyApi(session=session, selector=ApiSelector.virtual_line)
self.push_to_talk = PushToTalkApi(session=session, selector=ApiSelector.virtual_line)
self.voicemail = VoicemailApi(session=session, selector=ApiSelector.virtual_line)
[docs]
def create(self, first_name: str, last_name: str, location_id: str, display_name: str = None,
phone_number: str = None, extension: str = None, caller_id_last_name: str = None,
caller_id_first_name: str = None, caller_id_number: str = None,
org_id: str = None) -> str:
"""
Create a Virtual Line
Create new Virtual Line for the given location.
Virtual line is a capability in Webex Calling that allows administrators to configure multiple lines to Webex
Calling users.
Creating a virtual line requires a full or user administrator auth token with a scope of
`spark-admin:telephony_config_write`.
:param first_name: First name defined for a virtual line. Minimum length is 1. Maximum length is 30.
:type first_name: str
:param last_name: Last name defined for a virtual line. Minimum length is 1. Maximum length is 30.
:type last_name: str
:param location_id: ID of location for virtual line.
:type location_id: str
:param display_name: Display name defined for a virtual line.
:type display_name: str
:param phone_number: Phone number of a virtual line. Minimum length is 1. Maximum length is 23. Either
`phoneNumber` or `extension` is mandatory.
:type phone_number: str
:param extension: Extension of a virtual line. Minimum length is 2. Maximum length is 10. Either `phoneNumber`
or `extension` is mandatory.
:type extension: str
:param caller_id_last_name: Last name used in the Calling Line ID and for dial-by-name functions. Minimum
length is 1. Maximum length is 30.
:type caller_id_last_name: str
:param caller_id_first_name: First name used in the Calling Line ID and for dial-by-name functions. Minimum
length is 1. Maximum length is 30.
:type caller_id_first_name: str
:param caller_id_number: Phone number to appear as the CLID for all calls. Minimum length is 1. Maximum length
is 23.
:type caller_id_number: str
:param org_id: Create the virtual line for this organization.
:type org_id: str
:rtype: str
"""
params = {}
if org_id is not None:
params['orgId'] = org_id
body = dict()
body['firstName'] = first_name
body['lastName'] = last_name
if display_name is not None:
body['displayName'] = display_name
if phone_number is not None:
body['phoneNumber'] = phone_number
if extension is not None:
body['extension'] = extension
body['locationId'] = location_id
if caller_id_last_name is not None:
body['callerIdLastName'] = caller_id_last_name
if caller_id_first_name is not None:
body['callerIdFirstName'] = caller_id_first_name
if caller_id_number is not None:
body['callerIdNumber'] = caller_id_number
url = self.ep()
data = super().post(url, params=params, json=body)
r = data['id']
return r
[docs]
def delete(self, virtual_line_id: str, org_id: str = None):
"""
Delete a Virtual Line
Delete the designated Virtual Line.
Virtual line is a capability in Webex Calling that allows administrators to configure multiple lines to Webex
Calling users.
Deleting a virtual line requires a full or user administrator auth token with a scope of
`spark-admin:telephony_config_write`.
:param virtual_line_id: Delete the virtual line with the matching ID.
:type virtual_line_id: str
:param org_id: Delete the virtual line from this organization.
:type org_id: str
:rtype: None
"""
params = {}
if org_id is not None:
params['orgId'] = org_id
url = self.ep(f'{virtual_line_id}')
super().delete(url, params=params)
[docs]
def details(self, virtual_line_id: str, org_id: str = None) -> VirtualLine:
"""
Get Details for a Virtual Line
Retrieve Virtual Line details.
Virtual line is a capability in Webex Calling that allows administrators to configure multiple lines to Webex
Calling users.
Retrieving virtual line details requires a full or user or read-only administrator or location administrator
auth token with a scope of `spark-admin:telephony_config_read`.
:param virtual_line_id: Retrieve settings for a virtual line with the matching ID.
:type virtual_line_id: str
:param org_id: Retrieve virtual line settings from this organization.
:type org_id: str
:rtype: :class:`GetVirtualLineObject`
"""
params = {}
if org_id is not None:
params['orgId'] = org_id
url = self.ep(f'{virtual_line_id}')
data = super().get(url, params=params)
r = VirtualLine.model_validate(data)
return r
[docs]
def update(self, virtual_line_id: str, first_name: str = None, last_name: str = None,
display_name: str = None, phone_number: str = None, extension: str = None,
announcement_language: str = None, caller_id_last_name: str = None,
caller_id_first_name: str = None, caller_id_number: str = None, time_zone: str = None,
org_id: str = None):
"""
Update a Virtual Line
Update the designated Virtual Line.
Virtual line is a capability in Webex Calling that allows administrators to configure multiple lines to Webex
Calling users.
Updating a virtual line requires a full or user or location administrator auth token with a scope of
`spark-admin:telephony_config_write`.
:param virtual_line_id: Update settings for a virtual line with the matching ID.
:type virtual_line_id: str
:param first_name: First name defined for a virtual line. Minimum length is 1. Maximum length is 30.
:type first_name: str
:param last_name: Last name defined for a virtual line. Minimum length is 1. Maximum length is 30.
:type last_name: str
:param display_name: Display name defined for a virtual line.
:type display_name: str
:param phone_number: Phone number of a virtual line. Minimum length is 1. Maximum length is 23. Either
`phoneNumber` or `extension` is mandatory.
:type phone_number: str
:param extension: Extension of a virtual line. Minimum length is 2. Maximum length is 10. Either `phoneNumber`
or `extension` is mandatory.
:type extension: str
:param announcement_language: Virtual Line's announcement language.
:type announcement_language: str
:param caller_id_last_name: Last name used in the Calling Line ID and for dial-by-name functions. Minimum
length is 1. Maximum length is 30.
:type caller_id_last_name: str
:param caller_id_first_name: First name used in the Calling Line ID and for dial-by-name functions. Minimum
length is 1. Maximum length is 30.
:type caller_id_first_name: str
:param caller_id_number: Phone number to appear as the CLID for all calls. Minimum length is 1. Maximum length
is 23.
:type caller_id_number: str
:param time_zone: Time zone defined for the virtual line.
:type time_zone: str
:param org_id: Update virtual line settings from this organization.
:type org_id: str
:rtype: None
"""
params = {}
if org_id is not None:
params['orgId'] = org_id
body = dict()
if first_name is not None:
body['firstName'] = first_name
if last_name is not None:
body['lastName'] = last_name
if display_name is not None:
body['displayName'] = display_name
if phone_number is not None:
body['phoneNumber'] = phone_number
if extension is not None:
body['extension'] = extension
if announcement_language is not None:
body['announcementLanguage'] = announcement_language
if caller_id_last_name is not None:
body['callerIdLastName'] = caller_id_last_name
if caller_id_first_name is not None:
body['callerIdFirstName'] = caller_id_first_name
if caller_id_number is not None:
body['callerIdNumber'] = caller_id_number
if time_zone is not None:
body['timeZone'] = time_zone
url = self.ep(f'{virtual_line_id}')
super().put(url, params=params, json=body)
[docs]
def get_phone_number(self, virtual_line_id: str,
org_id: str = None) -> VirtualLineNumberPhoneNumber:
"""
Get Phone Number assigned for a Virtual Line
Get details on the assigned phone number and extension for the virtual line.
Retrieving virtual line phone number details requires a full or user or read-only administrator auth token
with
a scope of `spark-admin:telephony_config_read`.
:param virtual_line_id: Retrieve settings for a virtual line with the matching ID.
:type virtual_line_id: str
:param org_id: Retrieve virtual line settings from this organization.
:type org_id: str
:rtype: GetVirtualLineNumberObjectPhoneNumber
"""
params = {}
if org_id is not None:
params['orgId'] = org_id
url = self.ep(f'{virtual_line_id}/number')
data = super().get(url, params=params)
r = VirtualLineNumberPhoneNumber.model_validate(data['phoneNumber'])
return r
[docs]
def update_directory_search(self, virtual_line_id: str, enabled: bool, org_id: str = None):
"""
Update Directory search for a Virtual Line
Update the directory search for a designated Virtual Line.
Virtual line is a capability in Webex Calling that allows administrators to configure multiple lines to Webex
Calling users.
Updating Directory search for a virtual line requires a full or user administrator auth token with a scope of
`spark-admin:telephony_config_write`.
:param virtual_line_id: Update settings for a virtual line with the matching ID.
:type virtual_line_id: str
:param enabled: Whether or not the directory search for a virtual line is enabled.
:type enabled: bool
:param org_id: Update virtual line settings from this organization.
:type org_id: str
:rtype: None
"""
params = {}
if org_id is not None:
params['orgId'] = org_id
body = dict()
body['enabled'] = enabled
url = self.ep(f'{virtual_line_id}/directorySearch')
super().put(url, params=params, json=body)
[docs]
def assigned_devices(self, virtual_line_id: str, org_id: str = None) -> VirtualLineDevices:
"""
Get List of Devices assigned for a Virtual Line
Retrieve Device details assigned for a virtual line.
Virtual line is a capability in Webex Calling that allows administrators to configure multiple lines to Webex
Calling users.
Retrieving the assigned device detials for a virtual line requires a full or user or read-only administrator
auth token with a scope of `spark-admin:telephony_config_read`.
:param virtual_line_id: Retrieve settings for a virtual line with the matching ID.
:type virtual_line_id: str
:param org_id: Retrieve virtual line settings from this organization.
:type org_id: str
:rtype: :class:`VirtualLineDevices`
"""
params = {}
if org_id is not None:
params['orgId'] = org_id
url = self.ep(f'{virtual_line_id}/devices')
data = super().get(url, params=params)
r = VirtualLineDevices.model_validate(data)
return r
[docs]
def dect_networks(self, virtual_line_id: str, org_id: str = None) -> list[AssignedDectNetwork]:
"""
Get List of Dect Networks Handsets for a Virtual Line
Retrieve DECT Network details assigned for a virtual line.
Virtual line is a capability in Webex Calling that allows administrators to configure multiple lines to Webex
Calling users.
Retrieving the assigned device detials for a virtual line requires a full or user or read-only administrator
auth token with a scope of `spark-admin:telephony_config_read`.
:param virtual_line_id: Retrieve settings for a virtual line with the matching ID.
:type virtual_line_id: str
:param org_id: Retrieve virtual line settings from this organization.
:type org_id: str
:rtype: list[AssignedDectNetwork]
"""
params = {}
if org_id is not None:
params['orgId'] = org_id
url = self.ep(f'{virtual_line_id}/dectNetworks')
data = super().get(url, params=params)
r = TypeAdapter(list[AssignedDectNetwork]).validate_python(data['dectNetworks'])
return r
[docs]
def list(self, org_id: str = None, location_id: list[str] = None,
id: list[str] = None, owner_name: list[str] = None, phone_number: list[str] = None,
location_name: list[str] = None, order: list[str] = None, has_device_assigned: bool = None,
has_extension_assigned: bool = None, has_dn_assigned: bool = None,
**params) -> Generator[VirtualLine, None, None]:
"""
List all Virtual Lines for the organization.
Virtual line is a capability in Webex Calling that allows administrators to configure multiple lines to Webex
Calling users.
Retrieving this list requires a full or read-only administrator auth token with a scope
of spark-admin:telephony_config_read.
:param org_id: List virtual lines for this organization.
:type org_id: str
:param location_id: Return the list of virtual lines matching these location ids. Example for multiple values -
?locationId=locId1&locationId=locId2.
:type location_id: List[str]
:param id: Return the list of virtual lines matching these virtualLineIds.
:type id: List[str]
:param owner_name: Return the list of virtual lines matching these owner names.
:type owner_name: List[str]
:param phone_number: Return the list of virtual lines matching these phone numbers.
:type phone_number: List[str]
:param location_name: Return the list of virtual lines matching the location names.
:type location_name: List[str]
:param order: Return the list of virtual lines based on the order. Default sort will be in an Ascending order.
Maximum 3 orders allowed at a time.
:type order: List[str]
:param has_device_assigned: If true, includes only virtual lines with devices assigned. When not explicitly
specified, the default includes both virtual lines with devices assigned and not assigned.
:type has_device_assigned: bool
:param has_extension_assigned: If true, includes only virtual lines with an extension assigned. When not
explicitly specified, the default includes both virtual lines with extension assigned and not assigned.
:type has_extension_assigned: bool
:param has_dn_assigned: If true, includes only virtual lines with an assigned directory number, also known as a
Dn. When not explicitly specified, the default includes both virtual lines with a Dn assigned and not
assigned.
:type has_dn_assigned: bool
"""
if org_id is not None:
params['orgId'] = org_id
if location_id is not None:
params['locationId'] = location_id
if id is not None:
params['id'] = id
if owner_name is not None:
params['ownerName'] = owner_name
if phone_number is not None:
params['phoneNumber'] = phone_number
if location_name is not None:
params['locationName'] = location_name
if order is not None:
params['order'] = order
if has_device_assigned is not None:
params['hasDeviceAssigned'] = has_device_assigned
if has_extension_assigned is not None:
params['hasExtensionAssigned'] = has_extension_assigned
if has_dn_assigned is not None:
params['hasDnAssigned'] = has_dn_assigned
url = self.ep()
return self.session.follow_pagination(url=url, model=VirtualLine, params=params, item_key='virtualLines')