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 AssignedDectNetwork, PrimaryOrShared, UserNumber
from ...locations import LocationAddress
from ...person_settings import TelephonyDevice
from ...person_settings.agent_caller_id import AgentCallerIdApi
from ...person_settings.available_numbers import AvailableNumbersApi
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 CallerIdApi, ExternalCallerIdNamePolicy
from ...person_settings.common import ApiSelector
from ...person_settings.dnd import DndApi
from ...person_settings.ecbn import ECBNApi
from ...person_settings.forwarding import PersonForwardingApi
from ...person_settings.moh import MusicOnHoldApi
from ...person_settings.outbound_billing_plan import OutboundBillingPlanApi
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
from ...rest import RestSession
__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
#: The display name defined for the 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
#: DND settings
dnd: DndApi
#: ECBN settings
ecbn: ECBNApi
#: forwarding settings
forwarding: PersonForwardingApi
#: music on hold settings
music_on_hold: MusicOnHoldApi
#: outbound billing plan settings
outbound_billing_plan: OutboundBillingPlanApi
#: 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: RestSession) -> None:
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.dnd = DndApi(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.outbound_billing_plan = OutboundBillingPlanApi(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, user, or location 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, user, or location 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, user, 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, user, or location administrator auth token with a scope of
`spark-admin:telephony_config_write` and `identity:contacts_rw`.
: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 64.
: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 64.
: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 128.
: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.
Virtual lines can be assigned phone numbers and extensions to enable calling functionality. This information is
essential for configuring and managing virtual line communication settings.
Retrieving virtual line phone number details requires a full, 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, user, or location administrator auth token with a
scope of `spark-admin:telephony_config_write` and `identity:contacts_rw`.
: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, 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, user, read-only, or location 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')