Source code for wxc_sdk.telephony.announcements_repo

"""
Not supported for Webex for Government (FedRAMP)
Features: Announcement Repository support reading and writing of Webex Calling Announcement Repository settings for
a specific organization.
"""

import os
from collections.abc import Generator
from datetime import datetime
from io import BufferedReader
from typing import Optional, Union

from pydantic import Field
from requests_toolbelt import MultipartEncoder

from ...api_child import ApiChild
from ...base import ApiModel
from ...common import AnnouncementLevel, IdAndName, MediaFileType

__all__ = ['RepoAnnouncement', 'AnnouncementsRepositoryApi', 'RepositoryUsage', 'FeatureReference']


[docs] class FeatureReference(ApiModel): #: Unique identifier of the call feature referenced. The call Feature can be Auto Attendant, Call Queue or Music #: On hold. id: Optional[str] = None #: Name of the call feature referenced. name: Optional[str] = None #: Resource Type of the call feature. type: Optional[str] = None #: Unique identifier of the location. location_id: Optional[str] = None #: Location name of the announcement file. location_name: Optional[str] = None
[docs] class RepoAnnouncement(IdAndName): #: File name of the uploaded binary announcement greeting. file_name: Optional[str] = None #: Size of the file in kilobytes. file_size: Optional[int] = None #: Media file type of the announcement file. media_file_type: Optional[MediaFileType] = None #: LastUpdated timestamp (in UTC format) of the announcement. last_updated: Optional[datetime] = None #: The level at which this announcement exists. level: Optional[AnnouncementLevel] = None #: The details of location at which this announcement exists. location: Optional[IdAndName] = None #: The below is not returned by list(), only by details() #: Reference count of the call features this announcement is assigned to. feature_reference_count: Optional[int] = None #: Call features referenced by this announcement. feature_references: Optional[list[FeatureReference]] = None #: list of playlists this announcement is assigned to playlists: Optional[list[IdAndName]] = None
[docs] class RepositoryUsage(ApiModel): #: Total file size used by announcements in this repository in kilobytes. total_file_size_used_kb: Optional[int] = Field(alias='totalFileSizeUsedKB', default=None) #: Maximum audio file size allowed to upload in kilobytes. max_audio_file_size_allowed_kb: Optional[int] = Field(alias='maxAudioFileSizeAllowedKB', default=None) #: Maximum video file size allowed to upload in kilobytes. max_video_file_size_allowed_kb: Optional[int] = Field(alias='maxVideoFileSizeAllowedKB', default=None) #: Total file size limit for the repository in megabytes. total_file_size_limit_mb: Optional[int] = Field(alias='totalFileSizeLimitMB', default=None)
[docs] class AnnouncementsRepositoryApi(ApiChild, base='telephony/config'): """ Not supported for Webex for Government (FedRAMP) Features: Announcement Repository support reading and writing of Webex Calling Announcement Repository settings for a specific organization. Viewing these read-only organization settings requires a full or read-only administrator auth token with a scope of spark-admin:telephony_config_read. Modifying these organization settings requires a full administrator auth token with a scope of spark-admin:telephony_config_write. A partner administrator can retrieve or change settings in a customer's organization using the optional orgId query parameter. """
[docs] def list( self, location_id: str = None, order: str = None, file_name: str = None, file_type: str = None, media_file_type: str = None, name: str = None, org_id: str = None, **params, ) -> Generator[RepoAnnouncement, None, None]: """ Fetch list of announcement greetings on location and organization level Fetch a list of binary announcement greetings at an organization as well as location level. An admin can upload a file at an organization level. This file will be uploaded to the announcement repository. This API requires a full or read-only administrator or location administrator auth token with a scope of `spark-admin:telephony_config_read`. :param location_id: Return the list of enterprise or Location announcement files. Without this parameter, the Enterprise level announcements are returned. Possible values: all, locations, Y2lzY29zcGFyazovL3VzL0xPQ0FUSU9OLzMxMTYx :type location_id: str :param order: Sort the list according to fileName or fileSize. The default sort will be in Ascending order. :type order: str :param file_name: Return the list of announcements with the given fileName. :type file_name: str :param file_type: Return the list of announcement files for this fileType. :type file_type: str :param media_file_type: Return the list of announcement files for this mediaFileType. :type media_file_type: str :param name: Return the list of announcement files for this announcement label. :type name: str :param org_id: Create an announcement in this organization. :type org_id: str :return: yields :class:`RepoAnnouncement` objects """ if org_id is not None: params['orgId'] = org_id if location_id is not None: params['locationId'] = location_id if order is not None: params['order'] = order if file_name is not None: params['fileName'] = file_name if file_type is not None: params['fileType'] = file_type if media_file_type is not None: params['mediaFileType'] = media_file_type if name is not None: params['name'] = name url = self.ep('announcements') return self.session.follow_pagination(url=url, model=RepoAnnouncement, item_key='announcements', params=params)
def _upload_or_modify(self, *, url, name, file, upload_as, params, is_upload) -> dict: """ :meta private: """ """async async def _upload_or_modify(self, *, url, name, file, upload_as, params, is_upload) -> dict: if isinstance(file, str): upload_as = upload_as or os.path.basename(file) file = open(file, mode='rb') must_close = True else: must_close = False # an existing reader if not upload_as: raise ValueError('upload_as is required') encoder = MultipartEncoder({'name': name, 'file': (upload_as, file, 'audio/wav')}) if is_upload: meth = super().post else: meth = super().put try: data = await meth(url, data=encoder, headers={'Content-Type': encoder.content_type}, params=params) finally: if must_close: file.close() return data """ if isinstance(file, str): upload_as = upload_as or os.path.basename(file) file = open(file, mode='rb') must_close = True else: must_close = False # an existing reader if not upload_as: raise ValueError('upload_as is required') encoder = MultipartEncoder({'name': name, 'file': (upload_as, file, 'audio/wav')}) if is_upload: meth = super().post else: meth = super().put try: data = meth(url, data=encoder, headers={'Content-Type': encoder.content_type}, params=params) finally: if must_close: file.close() return data
[docs] def upload_announcement( self, name: str, file: Union[BufferedReader, str], upload_as: str = None, location_id: str = None, org_id: str = None, ) -> str: """ Upload a binary announcement greeting at organization or location level Upload a binary file to the announcement repository at organization or location level. An admin can upload a file at an organization or location level. This file will be uploaded to the announcement repository. This API requires a full administrator auth token with a scope of spark-admin:telephony_config_write . :param name: The announcement file name (e.g., "greeting.wav"). This is a required field. :type name: str :param file: the file to be uploaded, can be a path to a file or a buffered reader (opened file); if a reader referring to an open file is passed then make sure to open the file as binary b/c otherwise the content length might be calculated wrong. Must be in WAV format :type file: Union[BufferedReader, str] :param upload_as: filename for the content. Only required if content is a reader; has to be a .wav file name. :type upload_as: str :param location_id: Unique identifier of a location where an announcement is being created. :type location_id: str :param org_id: Create an announcement in this organization. :type org_id: str :return: id of announcement :rtype: str Examples: .. code-block:: python # upload a local file as announcement at the org level r = api.telephony.announcements_repo.upload_announcement(name='Sample', file='sample.wav') # upload an announcement from an open file # any files-like object can be used as input. # note: the upload_as parameter is required to set the file name for the upload with open('sample.wav', mode='rb') as wav_file: r = api.telephony.announcements_repo.upload_announcement(name='Sample', file=wav_file, upload_as='sample.wav') # upload an announcement from content in a string with open('sample.wav', mode='rb') as wav_file: data = wav_file.read() # data now is a bytes object with the file content. As we can use files-like objects as input # it's also possible to use a BytesIO as input for upload_announcement() binary_file = io.BytesIO(data) r = self.api.telephony.announcements_repo.upload_announcement(name='Sample', file=binary_file, upload_as='from_string.wav') """ """async async def upload_announcement(self, name: str, file: Union[BufferedReader, str], upload_as: str = None, location_id: str = None, org_id: str = None) -> str: params = org_id and {'orgId': org_id} or None if location_id is None: url = self.ep('announcements') else: url = self.ep(f'locations/{location_id}/announcements') data = await self._upload_or_modify(url=url, name=name, file=file, upload_as=upload_as, params=params, is_upload=True) return data["id"] """ params = org_id and {'orgId': org_id} or None if location_id is None: url = self.ep('announcements') else: url = self.ep(f'locations/{location_id}/announcements') data = self._upload_or_modify(url=url, name=name, file=file, upload_as=upload_as, params=params, is_upload=True) return data['id']
[docs] def usage(self, location_id: str = None, org_id: str = None) -> RepositoryUsage: """ Fetch repository usage for announcements for an organization or location Retrieves repository usage for announcements for an organization or location This API requires a full or read-only administrator auth token with a scope of spark-admin:telephony_config_read. :param location_id: Unique identifier of a location :type location_id: str :param org_id: Create an announcement in this organization. :type org_id: str """ params = org_id and {'orgId': org_id} or None if location_id is None: url = self.ep('announcements/usage') else: url = self.ep(f'locations/{location_id}/announcements/usage') data = super().get(url=url, params=params) return RepositoryUsage.model_validate(data)
[docs] def details(self, announcement_id: str, location_id: str = None, org_id: str = None) -> RepoAnnouncement: """ Fetch details of a binary announcement greeting at the organization or location level Fetch details of a binary announcement greeting by its ID at an organization level. An admin can upload a file at an organization level. This file will be uploaded to the announcement repository. This API requires a full or read-only administrator auth token with a scope of spark-admin:telephony_config_read. :param location_id: Unique identifier of a location :type location_id: str :param announcement_id: Unique identifier of an announcement. :type announcement_id: str :param org_id: Get details of an announcement in this organization. :type org_id: str """ params = org_id and {'orgId': org_id} or None if location_id is None: url = self.ep(f'announcements/{announcement_id}') else: url = self.ep(f'locations/{location_id}/announcements/{announcement_id}') data = super().get(url=url, params=params) return RepoAnnouncement.model_validate(data)
[docs] def delete(self, announcement_id: str, location_id: str = None, org_id: str = None): """ Delete an announcement greeting. This API requires a full administrator auth token with a scope of spark-admin:telephony_config_write. :param announcement_id: Unique identifier of an announcement. :type announcement_id: str :param location_id: Unique identifier of a location where announcement is being deleted. :type location_id: str :param org_id: Delete an announcement in this organization. :type org_id: str """ params = org_id and {'orgId': org_id} or None if location_id is None: url = self.ep(f'announcements/{announcement_id}') else: url = self.ep(f'locations/{location_id}/announcements/{announcement_id}') super().delete(url=url, params=params)
[docs] def modify( self, announcement_id: str, name: str, file: Union[BufferedReader, str], upload_as: str = None, location_id: str = None, org_id: str = None, ): """ Modify a binary announcement greeting at organization or location level Modify an existing announcement greeting at a organization or location level. An admin can upload a file or modify an existing file at a location level. This file will be uploaded to the announcement repository. Your request will need to be a `multipart/form-data` request rather than JSON, using the `audio/wav` Content-Type. This API requires a full administrator auth token with a scope of `spark-admin:telephony_config_write`. :param announcement_id: Unique identifier of an announcement. :type announcement_id: str :param name: Announcement name :type name: str :param file: the file to be uploaded, can be a path to a file or a buffered reader (opened file); if a reader referring to an open file is passed then make sure to open the file as binary b/c otherwise the content length might be calculated wrong :type file: Union[BufferedReader, str] :param upload_as: filename for the content. Only required if content is a reader; has to be a .wav file name. :type upload_as: str :param location_id: Unique identifier of a location where announcement is being deleted. :type location_id: str :param org_id: Modify an announcement in this organization. :type org_id: str """ """async async def modify(self, announcement_id: str, name: str, file: Union[BufferedReader, str], upload_as: str = None, location_id: str = None, org_id: str = None): params = org_id and {'orgId': org_id} or None if location_id is None: url = self.ep(f'announcements/{announcement_id}') else: url = self.ep(f'locations/{location_id}/announcements/{announcement_id}') data = await self._upload_or_modify(url=url, name=name, file=file, upload_as=upload_as, params=params, is_upload=False) return data["id"] """ params = org_id and {'orgId': org_id} or None if location_id is None: url = self.ep(f'announcements/{announcement_id}') else: url = self.ep(f'locations/{location_id}/announcements/{announcement_id}') data = self._upload_or_modify( url=url, name=name, file=file, upload_as=upload_as, params=params, is_upload=False ) return data['id']