def __init__(self,
                 account_id=None,
                 conference_id=None,
                 name=None,
                 recording_id=None,
                 duration=None,
                 channels=None,
                 start_time=None,
                 end_time=None,
                 file_format=None,
                 status=None,
                 media_url=None):
        """Constructor for the ConferenceRecordingMetadata class"""

        # Initialize members of the class
        self.account_id = account_id
        self.conference_id = conference_id
        self.name = name
        self.recording_id = recording_id
        self.duration = duration
        self.channels = channels
        self.start_time = APIHelper.RFC3339DateTime(
            start_time) if start_time else None
        self.end_time = APIHelper.RFC3339DateTime(
            end_time) if end_time else None
        self.file_format = file_format
        self.status = status
        self.media_url = media_url
    def get_stream_recording_media(self,
                                   account_id,
                                   call_id,
                                   recording_id):
        """Does a GET request to /api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}/media.

        Downloads the specified recording

        Args:
            account_id (string): TODO: type description here.
            call_id (string): TODO: type description here.
            recording_id (string): TODO: type description here.

        Returns:
            binary: Response from the API. successful operation

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}/media'
        _url_path = APIHelper.append_url_with_template_parameters(_url_path, {
            'accountId': account_id,
            'callId': call_id,
            'recordingId': recording_id
        })
        _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT)
        _query_builder += _url_path
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare and execute request
        _request = self.config.http_client.get(_query_url)
        VoiceBasicAuth.apply(self.config, _request)
        _response = self.execute_request(_request, binary=True)

        # Endpoint and global error handling using HTTP status codes.
        if _response.status_code == 400:
            raise ApiErrorResponseException('Something\'s not quite right... Either your request is invalid or you\'re requesting it at a bad time. Please fix it before trying again.', _response)
        elif _response.status_code == 401:
            raise APIException('Please authenticate yourself.', _response)
        elif _response.status_code == 403:
            raise ApiErrorResponseException('Your credentials are invalid. Please use your API credentials for the Bandwidth Dashboard.', _response)
        elif _response.status_code == 404:
            raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response)
        elif _response.status_code == 415:
            raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response)
        elif _response.status_code == 429:
            raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response)
        elif _response.status_code == 500:
            raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response)
        self.validate_response(_response)

        decoded = _response.text
        _result = ApiResponse(_response, body=decoded)
        return _result
Exemple #3
0
    def create_message(self,
                       user_id,
                       body=None):
        """Does a POST request to /users/{userId}/messages.

        createMessage

        Args:
            user_id (string): TODO: type description here.
            body (MessageRequest, optional): TODO: type description here.

        Returns:
            BandwidthMessage: Response from the API. successful operation

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/users/{userId}/messages'
        _url_path = APIHelper.append_url_with_template_parameters(_url_path, {
            'userId': user_id
        })
        _query_builder = self.config.get_base_uri(Server.MESSAGINGDEFAULT)
        _query_builder += _url_path
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'accept': 'application/json',
            'content-type': 'application/json; charset=utf-8'
        }

        # Prepare and execute request
        _request = self.config.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body))
        MessagingBasicAuth.apply(self.config, _request)
        _response = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _response.status_code == 400:
            raise MessagingException('400 Request is malformed or invalid', _response)
        elif _response.status_code == 401:
            raise MessagingException('401 The specified user does not have access to the account', _response)
        elif _response.status_code == 403:
            raise MessagingException('403 The user does not have access to this API', _response)
        elif _response.status_code == 404:
            raise MessagingException('404 Path not found', _response)
        elif _response.status_code == 415:
            raise MessagingException('415 The content-type of the request is incorrect', _response)
        elif _response.status_code == 429:
            raise MessagingException('429 The rate limit has been reached', _response)
        self.validate_response(_response)

        decoded = APIHelper.json_deserialize(_response.text, BandwidthMessage.from_dictionary)
        _result = ApiResponse(_response, body=decoded)
        return _result
Exemple #4
0
    def delete_media(self,
                     account_id,
                     media_id):
        """Does a DELETE request to /users/{accountId}/media/{mediaId}.

        Deletes a media file from Bandwidth API server. Make sure you don't
        have any application scripts still using the media before you delete.
        If you accidentally delete a media file, you can immediately upload a
        new file with the same name.

        Args:
            account_id (string): User's account ID
            media_id (string): The media ID to delete

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers.

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/users/{accountId}/media/{mediaId}'
        _url_path = APIHelper.append_url_with_template_parameters(_url_path, {
            'accountId': {'value': account_id, 'encode': False},
            'mediaId': {'value': media_id, 'encode': False}
        })
        _query_builder = self.config.get_base_uri(Server.MESSAGINGDEFAULT)
        _query_builder += _url_path
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare and execute request
        _request = self.config.http_client.delete(_query_url)
        MessagingBasicAuth.apply(self.config, _request)
        _response = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _response.status_code == 400:
            raise MessagingException('400 Request is malformed or invalid', _response)
        elif _response.status_code == 401:
            raise MessagingException('401 The specified user does not have access to the account', _response)
        elif _response.status_code == 403:
            raise MessagingException('403 The user does not have access to this API', _response)
        elif _response.status_code == 404:
            raise MessagingException('404 Path not found', _response)
        elif _response.status_code == 415:
            raise MessagingException('415 The content-type of the request is incorrect', _response)
        elif _response.status_code == 429:
            raise MessagingException('429 The rate limit has been reached', _response)
        self.validate_response(_response)

        # Return appropriate type
        return ApiResponse(_response)
Exemple #5
0
    def get_media(self,
                  account_id,
                  media_id):
        """Does a GET request to /users/{accountId}/media/{mediaId}.

        Downloads a media file you previously uploaded.

        Args:
            account_id (string): User's account ID
            media_id (string): Media ID to retrieve

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers.
                successful operation

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/users/{accountId}/media/{mediaId}'
        _url_path = APIHelper.append_url_with_template_parameters(_url_path, {
            'accountId': {'value': account_id, 'encode': False},
            'mediaId': {'value': media_id, 'encode': False}
        })
        _query_builder = self.config.get_base_uri(Server.MESSAGINGDEFAULT)
        _query_builder += _url_path
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare and execute request
        _request = self.config.http_client.get(_query_url)
        MessagingBasicAuth.apply(self.config, _request)
        _response = self.execute_request(_request, binary=True)

        # Endpoint and global error handling using HTTP status codes.
        if _response.status_code == 400:
            raise MessagingException('400 Request is malformed or invalid', _response)
        elif _response.status_code == 401:
            raise MessagingException('401 The specified user does not have access to the account', _response)
        elif _response.status_code == 403:
            raise MessagingException('403 The user does not have access to this API', _response)
        elif _response.status_code == 404:
            raise MessagingException('404 Path not found', _response)
        elif _response.status_code == 415:
            raise MessagingException('415 The content-type of the request is incorrect', _response)
        elif _response.status_code == 429:
            raise MessagingException('429 The rate limit has been reached', _response)
        self.validate_response(_response)

        decoded = _response.text
        _result = ApiResponse(_response, body=decoded)
        return _result
Exemple #6
0
    def create_messaging_two_factor(self, account_id, body):
        """Does a POST request to /accounts/{accountId}/code/messaging.

        Two-Factor authentication with Bandwidth messaging services

        Args:
            account_id (string): Bandwidth Account ID with Messaging service
                enabled
            body (TwoFactorCodeRequestSchema): TODO: type description here.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers.
                successful operation

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/accounts/{accountId}/code/messaging'
        _url_path = APIHelper.append_url_with_template_parameters(
            _url_path, {'accountId': {
                'value': account_id,
                'encode': True
            }})
        _query_builder = self.config.get_base_uri(Server.TWOFACTORAUTHDEFAULT)
        _query_builder += _url_path
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'accept': 'application/json',
            'content-type': 'application/json; charset=utf-8'
        }

        # Prepare and execute request
        _request = self.config.http_client.post(
            _query_url,
            headers=_headers,
            parameters=APIHelper.json_serialize(body))
        TwoFactorAuthBasicAuth.apply(self.config, _request)
        _response = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _response.status_code == 400:
            raise InvalidRequestException('client request error', _response)
        self.validate_response(_response)

        decoded = APIHelper.json_deserialize(
            _response.text, TwoFactorMessagingResponse.from_dictionary)
        _result = ApiResponse(_response, body=decoded)
        return _result
    def delete_session(self, account_id, session_id):
        """Does a DELETE request to /accounts/{accountId}/sessions/{sessionId}.

        Delete session by ID.

        Args:
            account_id (string): Account ID
            session_id (string): Session ID

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. No
                Content

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/accounts/{accountId}/sessions/{sessionId}'
        _url_path = APIHelper.append_url_with_template_parameters(
            _url_path, {
                'accountId': {
                    'value': account_id,
                    'encode': False
                },
                'sessionId': {
                    'value': session_id,
                    'encode': False
                }
            })
        _query_builder = self.config.get_base_uri(Server.WEBRTCDEFAULT)
        _query_builder += _url_path
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare and execute request
        _request = self.config.http_client.delete(_query_url)
        WebRtcBasicAuth.apply(self.config, _request)
        _response = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _response.status_code == 401:
            raise APIException('Unauthorized', _response)
        elif _response.status_code == 403:
            raise APIException('Access Denied', _response)
        elif _response.status_code == 404:
            raise APIException('Not Found', _response)
        elif (_response.status_code < 200) or (_response.status_code > 208):
            raise ErrorException('Unexpected Error', _response)
        self.validate_response(_response)

        # Return appropriate type
        return ApiResponse(_response)
Exemple #8
0
    def get_media(self,
                  user_id,
                  media_id):
        """Does a GET request to /users/{userId}/media/{mediaId}.

        getMedia

        Args:
            user_id (string): TODO: type description here.
            media_id (string): TODO: type description here.

        Returns:
            binary: Response from the API. successful operation

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/users/{userId}/media/{mediaId}'
        _url_path = APIHelper.append_url_with_template_parameters(_url_path, {
            'userId': user_id,
            'mediaId': media_id
        })
        _query_builder = self.config.get_base_uri(Server.MESSAGINGDEFAULT)
        _query_builder += _url_path
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare and execute request
        _request = self.config.http_client.get(_query_url)
        MessagingBasicAuth.apply(self.config, _request)
        _response = self.execute_request(_request, binary=True)

        # Endpoint and global error handling using HTTP status codes.
        if _response.status_code == 400:
            raise MessagingException('400 Request is malformed or invalid', _response)
        elif _response.status_code == 401:
            raise MessagingException('401 The specified user does not have access to the account', _response)
        elif _response.status_code == 403:
            raise MessagingException('403 The user does not have access to this API', _response)
        elif _response.status_code == 404:
            raise MessagingException('404 Path not found', _response)
        elif _response.status_code == 415:
            raise MessagingException('415 The content-type of the request is incorrect', _response)
        elif _response.status_code == 429:
            raise MessagingException('429 The rate limit has been reached', _response)
        self.validate_response(_response)

        decoded = _response.text
        _result = ApiResponse(_response, body=decoded)
        return _result
Exemple #9
0
    def add_query_parameter(self, name, value):
        """ Add a query parameter to the HttpRequest.

        Args:
            name (string): The name of the query parameter.
            value (string): The value of the query parameter.

        """
        self.query_url = APIHelper.append_url_with_query_parameters(
            self.query_url, {name: value})
        self.query_url = APIHelper.clean_url(self.query_url)
    def __init__(self,
                 account_id=None,
                 call_id=None,
                 application_id=None,
                 to=None,
                 mfrom=None,
                 call_url=None,
                 answer_url=None,
                 answer_method=None,
                 disconnect_method=None,
                 start_time=None,
                 call_timeout=None,
                 disconnect_url=None,
                 username=None,
                 password=None,
                 tag=None):
        """Constructor for the ApiCallResponse class"""

        # Initialize members of the class
        self.account_id = account_id
        self.call_id = call_id
        self.application_id = application_id
        self.to = to
        self.mfrom = mfrom
        self.start_time = APIHelper.RFC3339DateTime(start_time) if start_time else None
        self.call_url = call_url
        self.call_timeout = call_timeout
        self.answer_url = answer_url
        self.answer_method = answer_method
        self.disconnect_url = disconnect_url
        self.disconnect_method = disconnect_method
        self.username = username
        self.password = password
        self.tag = tag
Exemple #11
0
def handle_messaging_callback():
    # raw_data = json.loads(request.data).pop()
    raw_data = APIHelper.json_deserialize(request.data).pop()
    messaging_callback: BandwidthCallbackMessage = BandwidthCallbackMessage.from_dictionary(
        raw_data)
    message: BandwidthMessage = messaging_callback.message
    is_dlr = message.direction.lower().strip() == 'out'
    if is_dlr:
        log_message = 'Callback Received for: MessageId: %s, status: %s'
        print(log_message % (message.id, messaging_callback.description))
        return 'Received Callback'
    owner = message.owner
    to_numbers = message.to.copy()
    to_numbers.remove(owner)
    to_numbers.append(message.mfrom)
    message_request = MessageRequest(
        application_id=BANDWIDTH_MSG_APPLICATION_ID,
        to=to_numbers,
        mfrom=owner)
    message_text = message.text.lower().strip()
    is_dog = message_text == 'dog'
    if is_dog:
        message_request.text = '🐶'
        message_request.media = ['https://bw-demo.s3.amazonaws.com/dog.jpg']
    else:
        message_request.text = '👋 Hello From bandwidth!'
    messaging_client: APIController = bandwidth_client.messaging_client.client
    api_response: ApiResponse = messaging_client.create_message(
        BANDWIDTH_ACCOUNT_ID, message_request)
    message_response: BandwidthMessage = api_response.body
    log_message = 'Sent message with MessageId: %s'
    print(log_message % message_response.id)
    return "Handle messaging callback"
Exemple #12
0
    def execute_request(self, request, binary=False):
        """Executes an HttpRequest.

        Args:
            request (HttpRequest): The HttpRequest to execute.
            binary (bool): A flag which should be set to True if
                a binary response is expected.

        Returns:
            HttpResponse: The HttpResponse received.

        """
        # Invoke the on before request HttpCallBack if specified
        if self.http_call_back is not None:
            self.http_call_back.on_before_request(request)

        # Add global headers to request
        request.headers = APIHelper.merge_dicts(self.global_headers(), request.headers)

        # Invoke the API call to fetch the response.
        func = self.config.http_client.execute_as_binary if binary else self.config.http_client.execute_as_string
        response = func(request)

        # Invoke the on after response HttpCallBack if specified
        if self.http_call_back is not None:
            self.http_call_back.on_after_response(response)

        return response
Exemple #13
0
    def __init__(self,
                 call_id=None,
                 parent_call_id=None,
                 application_id=None,
                 account_id=None,
                 to=None,
                 mfrom=None,
                 direction=None,
                 state=None,
                 identity=None,
                 stir_shaken=None,
                 start_time=None,
                 enqueued_time=None,
                 answer_time=None,
                 end_time=None,
                 disconnect_cause=None,
                 error_message=None,
                 error_id=None,
                 last_update=None):
        """Constructor for the CallState class"""

        # Initialize members of the class
        self.call_id = call_id
        self.parent_call_id = parent_call_id
        self.application_id = application_id
        self.account_id = account_id
        self.to = to
        self.mfrom = mfrom
        self.direction = direction
        self.state = state
        self.identity = identity
        self.stir_shaken = stir_shaken
        self.start_time = APIHelper.RFC3339DateTime(
            start_time) if start_time else None
        self.enqueued_time = APIHelper.RFC3339DateTime(
            enqueued_time) if enqueued_time else None
        self.answer_time = APIHelper.RFC3339DateTime(
            answer_time) if answer_time else None
        self.end_time = APIHelper.RFC3339DateTime(
            end_time) if end_time else None
        self.disconnect_cause = disconnect_cause
        self.error_message = error_message
        self.error_id = error_id
        self.last_update = APIHelper.RFC3339DateTime(
            last_update) if last_update else None
    def __init__(self,
                 application_id=None,
                 account_id=None,
                 call_id=None,
                 parent_call_id=None,
                 recording_id=None,
                 to=None,
                 mfrom=None,
                 transfer_caller_id=None,
                 transfer_to=None,
                 duration=None,
                 direction=None,
                 channels=None,
                 start_time=None,
                 end_time=None,
                 file_format=None,
                 status=None,
                 media_url=None,
                 transcription=None):
        """Constructor for the CallRecordingMetadata class"""

        # Initialize members of the class
        self.application_id = application_id
        self.account_id = account_id
        self.call_id = call_id
        self.parent_call_id = parent_call_id
        self.recording_id = recording_id
        self.to = to
        self.mfrom = mfrom
        self.transfer_caller_id = transfer_caller_id
        self.transfer_to = transfer_to
        self.duration = duration
        self.direction = direction
        self.channels = channels
        self.start_time = APIHelper.RFC3339DateTime(
            start_time) if start_time else None
        self.end_time = APIHelper.RFC3339DateTime(
            end_time) if end_time else None
        self.file_format = file_format
        self.status = status
        self.media_url = media_url
        self.transcription = transcription
Exemple #15
0
    def __init__(self,
                 id=None,
                 name=None,
                 created_time=None,
                 completed_time=None,
                 conference_event_url=None,
                 conference_event_method=None,
                 tag=None,
                 active_members=None):
        """Constructor for the ConferenceState class"""

        # Initialize members of the class
        self.id = id
        self.name = name
        self.created_time = APIHelper.RFC3339DateTime(
            created_time) if created_time else None
        self.completed_time = APIHelper.RFC3339DateTime(
            completed_time) if completed_time else None
        self.conference_event_url = conference_event_url
        self.conference_event_method = conference_event_method
        self.tag = tag
        self.active_members = active_members
    def __init__(self, reason, response):
        """Constructor for the ForbiddenRequestException class

        Args:
            reason (string): The reason (or error message) for the Exception
                to be raised.
            response (HttpResponse): The HttpResponse of the API call.

        """
        super(ForbiddenRequestException, self).__init__(reason, response)
        dictionary = APIHelper.json_deserialize(self.response.text)
        if isinstance(dictionary, dict):
            self.unbox(dictionary)
Exemple #17
0
    def __init__(self,
                 account_id=None,
                 call_id=None,
                 application_id=None,
                 to=None,
                 mfrom=None,
                 call_url=None,
                 answer_url=None,
                 answer_method=None,
                 disconnect_method=None,
                 enqueued_time=None,
                 call_timeout=None,
                 callback_timeout=None,
                 answer_fallback_url=None,
                 answer_fallback_method=None,
                 disconnect_url=None,
                 username=None,
                 password=None,
                 fallback_username=None,
                 fallback_password=None,
                 tag=None,
                 priority=None):
        """Constructor for the CreateCallResponse class"""

        # Initialize members of the class
        self.account_id = account_id
        self.call_id = call_id
        self.application_id = application_id
        self.to = to
        self.mfrom = mfrom
        self.enqueued_time = APIHelper.RFC3339DateTime(
            enqueued_time) if enqueued_time else None,
        self.enqueued_time = enqueued_time
        self.call_url = call_url
        self.call_timeout = call_timeout
        self.callback_timeout = callback_timeout
        self.answer_url = answer_url
        self.answer_method = answer_method
        self.answer_fallback_url = answer_fallback_url
        self.answer_fallback_method = answer_fallback_method
        self.disconnect_url = disconnect_url
        self.disconnect_method = disconnect_method
        self.username = username
        self.password = password
        self.fallback_username = fallback_username
        self.fallback_password = fallback_password
        self.tag = tag
        self.priority = priority
Exemple #18
0
    def get_base_uri(self, server=Server.DEFAULT):
        """Generates the appropriate base URI for the environment and the
        server.

        Args:
            server (Configuration.Server): The server enum for which the base
            URI is required.

        Returns:
            String: The base URI.

        """
        parameters = {
            "base_url": {
                'value': self.base_url,
                'encode': False
            },
        }

        return APIHelper.append_url_with_template_parameters(
            self.environments[self.environment][server], parameters)
    def create_participant(self, account_id, body=None):
        """Does a POST request to /accounts/{accountId}/participants.

        Create a new participant under this account.
        Participants are idempotent, so relevant parameters must be set in
        this function if desired.

        Args:
            account_id (string): Account ID
            body (Participant, optional): Participant parameters

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. Success

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/accounts/{accountId}/participants'
        _url_path = APIHelper.append_url_with_template_parameters(
            _url_path, {'accountId': {
                'value': account_id,
                'encode': False
            }})
        _query_builder = self.config.get_base_uri(Server.WEBRTCDEFAULT)
        _query_builder += _url_path
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'accept': 'application/json',
            'content-type': 'application/json; charset=utf-8'
        }

        # Prepare and execute request
        _request = self.config.http_client.post(
            _query_url,
            headers=_headers,
            parameters=APIHelper.json_serialize(body))
        WebRtcBasicAuth.apply(self.config, _request)
        _response = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _response.status_code == 400:
            raise APIException('Bad Request', _response)
        elif _response.status_code == 401:
            raise APIException('Unauthorized', _response)
        elif _response.status_code == 403:
            raise APIException('Access Denied', _response)
        elif (_response.status_code < 200) or (_response.status_code > 208):
            raise ErrorException('Unexpected Error', _response)
        self.validate_response(_response)

        decoded = APIHelper.json_deserialize(
            _response.text, AccountsParticipantsResponse.from_dictionary)
        _result = ApiResponse(_response, body=decoded)
        return _result
Exemple #20
0
    def upload_media(self,
                     account_id,
                     media_id,
                     body,
                     content_type='application/octet-stream',
                     cache_control=None):
        """Does a PUT request to /users/{accountId}/media/{mediaId}.

        Uploads a file the normal HTTP way. You may add headers to the request
        in order to provide some control to your media-file.

        Args:
            account_id (string): User's account ID
            media_id (string): The user supplied custom media ID
            body (typing.BinaryIO): TODO: type description here.
            content_type (string, optional): The media type of the
                entity-body
            cache_control (string, optional): General-header field is used to
                specify directives that MUST be obeyed by all caching
                mechanisms along the request/response chain.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers.

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/users/{accountId}/media/{mediaId}'
        _url_path = APIHelper.append_url_with_template_parameters(_url_path, {
            'accountId': {'value': account_id, 'encode': False},
            'mediaId': {'value': media_id, 'encode': False}
        })
        _query_builder = self.config.get_base_uri(Server.MESSAGINGDEFAULT)
        _query_builder += _url_path
        _query_url = APIHelper.clean_url(_query_builder)

        if isinstance(body, FileWrapper):
            body_wrapper = body.file_stream
            body_content_type = body.content_type
        else:
            body_wrapper = body
            body_content_type = content_type

        # Prepare headers
        _headers = {
            'content-type': body_content_type,
            'Cache-Control': cache_control
        }

        # Prepare and execute request
        _request = self.config.http_client.put(_query_url, headers=_headers, parameters=body_wrapper)
        MessagingBasicAuth.apply(self.config, _request)
        _response = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _response.status_code == 400:
            raise MessagingException('400 Request is malformed or invalid', _response)
        elif _response.status_code == 401:
            raise MessagingException('401 The specified user does not have access to the account', _response)
        elif _response.status_code == 403:
            raise MessagingException('403 The user does not have access to this API', _response)
        elif _response.status_code == 404:
            raise MessagingException('404 Path not found', _response)
        elif _response.status_code == 415:
            raise MessagingException('415 The content-type of the request is incorrect', _response)
        elif _response.status_code == 429:
            raise MessagingException('429 The rate limit has been reached', _response)
        self.validate_response(_response)

        # Return appropriate type
        return ApiResponse(_response)
Exemple #21
0
    def create_voice_two_factor(self, account_id, body):
        """Does a POST request to /accounts/{accountId}/code/voice.

        Multi-Factor authentication with Bandwidth Voice services. Allows for
        a user to send an MFA code via a phone call.

        Args:
            account_id (string): Bandwidth Account ID with Voice service
                enabled
            body (TwoFactorCodeRequestSchema): TODO: type description here.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers.
                successful operation

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/accounts/{accountId}/code/voice'
        _url_path = APIHelper.append_url_with_template_parameters(
            _url_path, {'accountId': {
                'value': account_id,
                'encode': False
            }})
        _query_builder = self.config.get_base_uri(
            Server.MULTIFACTORAUTHDEFAULT)
        _query_builder += _url_path
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'accept': 'application/json',
            'content-type': 'application/json; charset=utf-8'
        }

        # Prepare and execute request
        _request = self.config.http_client.post(
            _query_url,
            headers=_headers,
            parameters=APIHelper.json_serialize(body))
        MultiFactorAuthBasicAuth.apply(self.config, _request)
        _response = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _response.status_code == 400:
            raise ErrorWithRequestException(
                'If there is any issue with values passed in by the user',
                _response)
        elif _response.status_code == 401:
            raise UnauthorizedRequestException(
                'Authentication is either incorrect or not present', _response)
        elif _response.status_code == 403:
            raise ForbiddenRequestException(
                'The user is not authorized to access this resource',
                _response)
        elif _response.status_code == 500:
            raise ErrorWithRequestException(
                'An internal server error occurred', _response)
        self.validate_response(_response)

        decoded = APIHelper.json_deserialize(
            _response.text, TwoFactorVoiceResponse.from_dictionary)
        _result = ApiResponse(_response, body=decoded)
        return _result
    def update_participant_subscriptions(self,
                                         account_id,
                                         session_id,
                                         participant_id,
                                         body=None):
        """Does a PUT request to /accounts/{accountId}/sessions/{sessionId}/participants/{participantId}/subscriptions.

        Update a participant's subscriptions.
        This is a full update that will replace the participant's
        subscriptions. First call `getParticipantSubscriptions` if you need
        the current subscriptions. Call this function with no `Subscriptions`
        object to remove all subscriptions.

        Args:
            account_id (string): Account ID
            session_id (string): Session ID
            participant_id (string): Participant ID
            body (Subscriptions, optional): Initial state

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. No
                Content

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/accounts/{accountId}/sessions/{sessionId}/participants/{participantId}/subscriptions'
        _url_path = APIHelper.append_url_with_template_parameters(
            _url_path, {
                'accountId': {
                    'value': account_id,
                    'encode': False
                },
                'sessionId': {
                    'value': session_id,
                    'encode': False
                },
                'participantId': {
                    'value': participant_id,
                    'encode': False
                }
            })
        _query_builder = self.config.get_base_uri(Server.WEBRTCDEFAULT)
        _query_builder += _url_path
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {'content-type': 'application/json; charset=utf-8'}

        # Prepare and execute request
        _request = self.config.http_client.put(
            _query_url,
            headers=_headers,
            parameters=APIHelper.json_serialize(body))
        WebRtcBasicAuth.apply(self.config, _request)
        _response = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _response.status_code == 400:
            raise APIException('Bad Request', _response)
        elif _response.status_code == 401:
            raise APIException('Unauthorized', _response)
        elif _response.status_code == 403:
            raise APIException('Access Denied', _response)
        elif _response.status_code == 404:
            raise APIException('Not Found', _response)
        elif (_response.status_code < 200) or (_response.status_code > 208):
            raise ErrorException('Unexpected Error', _response)
        self.validate_response(_response)

        # Return appropriate type
        return ApiResponse(_response)
Exemple #23
0
    def list_media(self, user_id, continuation_token=None):
        """Does a GET request to /users/{userId}/media.

        listMedia

        Args:
            user_id (string): TODO: type description here.
            continuation_token (string, optional): TODO: type description
                here.

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers.
                successful operation

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/users/{userId}/media'
        _url_path = APIHelper.append_url_with_template_parameters(
            _url_path, {'userId': {
                'value': user_id,
                'encode': True
            }})
        _query_builder = self.config.get_base_uri(Server.MESSAGINGDEFAULT)
        _query_builder += _url_path
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'accept': 'application/json',
            'Continuation-Token': continuation_token
        }

        # Prepare and execute request
        _request = self.config.http_client.get(_query_url, headers=_headers)
        MessagingBasicAuth.apply(self.config, _request)
        _response = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _response.status_code == 400:
            raise MessagingException('400 Request is malformed or invalid',
                                     _response)
        elif _response.status_code == 401:
            raise MessagingException(
                '401 The specified user does not have access to the account',
                _response)
        elif _response.status_code == 403:
            raise MessagingException(
                '403 The user does not have access to this API', _response)
        elif _response.status_code == 404:
            raise MessagingException('404 Path not found', _response)
        elif _response.status_code == 415:
            raise MessagingException(
                '415 The content-type of the request is incorrect', _response)
        elif _response.status_code == 429:
            raise MessagingException('429 The rate limit has been reached',
                                     _response)
        self.validate_response(_response)

        decoded = APIHelper.json_deserialize(_response.text,
                                             Media.from_dictionary)
        _result = ApiResponse(_response, body=decoded)
        return _result
Exemple #24
0
    def upload_media(self,
                     user_id,
                     media_id,
                     content_length,
                     body,
                     content_type='application/octet-stream',
                     cache_control=None):
        """Does a PUT request to /users/{userId}/media/{mediaId}.

        uploadMedia

        Args:
            user_id (string): TODO: type description here.
            media_id (string): TODO: type description here.
            content_length (long|int): TODO: type description here.
            body (string): TODO: type description here.
            content_type (string, optional): TODO: type description here.
                Example: application/octet-stream
            cache_control (string, optional): TODO: type description here.

        Returns:
            void: Response from the API.

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/users/{userId}/media/{mediaId}'
        _url_path = APIHelper.append_url_with_template_parameters(_url_path, {
            'userId': user_id,
            'mediaId': media_id
        })
        _query_builder = self.config.get_base_uri(Server.MESSAGINGDEFAULT)
        _query_builder += _url_path
        _query_url = APIHelper.clean_url(_query_builder)

        if isinstance(body, FileWrapper):
            body_wrapper = body.file_stream
            body_content_type = body.content_type
        else:
            body_wrapper = body
            body_content_type = content_type

        # Prepare headers
        _headers = {
            'content-type': body_content_type,
            'Content-Length': content_length,
            'Cache-Control': cache_control
        }

        # Prepare and execute request
        _request = self.config.http_client.put(_query_url, headers=_headers, parameters=body_wrapper)
        MessagingBasicAuth.apply(self.config, _request)
        _response = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _response.status_code == 400:
            raise MessagingException('400 Request is malformed or invalid', _response)
        elif _response.status_code == 401:
            raise MessagingException('401 The specified user does not have access to the account', _response)
        elif _response.status_code == 403:
            raise MessagingException('403 The user does not have access to this API', _response)
        elif _response.status_code == 404:
            raise MessagingException('404 Path not found', _response)
        elif _response.status_code == 415:
            raise MessagingException('415 The content-type of the request is incorrect', _response)
        elif _response.status_code == 429:
            raise MessagingException('429 The rate limit has been reached', _response)
        self.validate_response(_response)

        # Return appropriate type
        ApiResponse(_response)
    def get_participant(self, account_id, participant_id):
        """Does a GET request to /accounts/{accountId}/participants/{participantId}.

        Get participant by ID.

        Args:
            account_id (string): Account ID
            participant_id (string): Participant ID

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers. Success

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/accounts/{accountId}/participants/{participantId}'
        _url_path = APIHelper.append_url_with_template_parameters(
            _url_path, {
                'accountId': {
                    'value': account_id,
                    'encode': False
                },
                'participantId': {
                    'value': participant_id,
                    'encode': False
                }
            })
        _query_builder = self.config.get_base_uri(Server.WEBRTCDEFAULT)
        _query_builder += _url_path
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {'accept': 'application/json'}

        # Prepare and execute request
        _request = self.config.http_client.get(_query_url, headers=_headers)
        WebRtcBasicAuth.apply(self.config, _request)
        _response = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _response.status_code == 401:
            raise APIException('Unauthorized', _response)
        elif _response.status_code == 403:
            raise APIException('Access Denied', _response)
        elif _response.status_code == 404:
            raise APIException('Not Found', _response)
        elif (_response.status_code < 200) or (_response.status_code > 208):
            raise ErrorException('Unexpected Error', _response)
        self.validate_response(_response)

        decoded = APIHelper.json_deserialize(_response.text,
                                             Participant.from_dictionary)
        _result = ApiResponse(_response, body=decoded)
        return _result
    def create_transcribe_recording(self,
                                    account_id,
                                    call_id,
                                    recording_id,
                                    body=None):
        """Does a POST request to /api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}/transcription.

        Requests that the specified recording be transcribed

        Args:
            account_id (string): TODO: type description here.
            call_id (string): TODO: type description here.
            recording_id (string): TODO: type description here.
            body (ApiTranscribeRecordingRequest, optional): TODO: type
                description here.

        Returns:
            void: Response from the API.

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/api/v2/accounts/{accountId}/calls/{callId}/recordings/{recordingId}/transcription'
        _url_path = APIHelper.append_url_with_template_parameters(_url_path, {
            'accountId': account_id,
            'callId': call_id,
            'recordingId': recording_id
        })
        _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT)
        _query_builder += _url_path
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'content-type': 'application/json; charset=utf-8'
        }

        # Prepare and execute request
        _request = self.config.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(body))
        VoiceBasicAuth.apply(self.config, _request)
        _response = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _response.status_code == 400:
            raise ApiErrorResponseException('Something\'s not quite right... Either your request is invalid or you\'re requesting it at a bad time. Please fix it before trying again.', _response)
        elif _response.status_code == 401:
            raise APIException('Please authenticate yourself.', _response)
        elif _response.status_code == 403:
            raise ApiErrorResponseException('Your credentials are invalid. Please use your API credentials for the Bandwidth Dashboard.', _response)
        elif _response.status_code == 404:
            raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response)
        elif _response.status_code == 410:
            raise ApiErrorResponseException('The media for this recording has been deleted, so we can\'t transcribe it', _response)
        elif _response.status_code == 415:
            raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response)
        elif _response.status_code == 429:
            raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response)
        elif _response.status_code == 500:
            raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response)
        self.validate_response(_response)

        # Return appropriate type
        ApiResponse(_response)
Exemple #27
0
def handle_callback():

    # Grab the incoming callback information
    raw_data = APIHelper.json_deserialize(request.data).pop()
    messaging_callback: BandwidthCallbackMessage = BandwidthCallbackMessage.from_dictionary(
        raw_data)
    message: BandwidthMessage = messaging_callback.message

    # Check the direction of the message - if we are receiving a callback saying our outbound message was sent,
    #  we dont want to reply with another generated trivia question
    is_dlr = message.direction.lower().strip() == 'out'
    if is_dlr:
        """Determine if the message is inbound or outbound and handle it"""
        log_message = 'Callback Received for: MessageId: %s, status: %s'
        print(log_message % (message.id, messaging_callback.description))
        return 'Outbound Message'

    question_type = ''
    question_difficulty = ''
    question_category = ''
    question = ''
    question_correct_answer = ''
    question_short_answer = ''
    question_incorrect_answers = ''

    # Parse the trivia question
    trivia_question = set_trivia_question()
    question_type = trivia_question['type']
    question_category = trivia_question['category']
    question = trivia_question['question']
    question_correct_answer = trivia_question['correct_answer']
    question_incorrect_answers = trivia_question['incorrect_answers']
    if trivia_question['difficulty'] == 'easy':
        question_difficulty = 1
    elif trivia_question['difficulty'] == 'medium':
        question_difficulty = 2
    elif trivia_question['difficulty'] == 'hard':
        question_difficulty = 3

    # Grab the message details and determine if user is new or existing, grab corresponding db record
    owner = message.owner
    respondents = message.mfrom
    database_user = determine_new_user(respondents)
    database_user.time = datetime.utcnow()
    # print('Owner', owner)
    # print('Respondents:', respondents)

    message_request = MessageRequest(
        application_id=BANDWIDTH_MSG_APPLICATION_ID,
        to=respondents,
        mfrom=owner)

    # Generate a question/answer set for multiple choice and format True/False
    if question_type == 'multiple':
        answers_list = question_incorrect_answers.copy()
        answers_list.append(question_correct_answer)
        random.shuffle(answers_list)
        answers_dict = {
            'A': answers_list[0],
            'B': answers_list[1],
            'C': answers_list[2],
            'D': answers_list[3]
        }

        # Match the correct letter answer from the dict key with the correct answer value after randomization
        for key in answers_dict:
            if question_correct_answer == answers_dict[key]:
                question_short_answer = str(key)
            else:
                pass
        question_text = str(question) + ' (' + str(question_difficulty) + ' pts.)' + '\n\n' + \
                        'A. ' + str(answers_list[0]) + '\n' + 'B. ' + str(answers_list[1]) + '\n' + \
                        'C. ' + str(answers_list[2]) + '\n' + 'D. ' + str(answers_list[3])

    elif question_type == 'boolean':
        question_text = 'True or False? (' + str(
            question_difficulty) + ' pts.)' + '\n\n' + str(question)
        answers_dict = {'T': 'True', 'F': 'False'}
        for key in answers_dict:
            if question_correct_answer == answers_dict[key]:
                question_short_answer = str(key)
            else:
                pass

    # If user is existing, see if they are sending an answer attempt and match it to the correct answer
    #  held in the database
    if message.text.lower().strip() == 'new':
        # If user is requesting a new question, clear their answer field and generate a new question
        database_user.currentQuestion = question
        database_user.currentAnswer = question_correct_answer
        database_user.currentShortAnswer = question_short_answer
        db.session.commit()
        message_request.text = str(question_text) + '\n\n' + 'Total Points: ' + str(database_user.points) + \
                               '\nText \'Help\' for help.\nText \'new\' to generate a new question. ' \
                               '\nText \'delete\' to permanently delete your account. \nThanks for playing Text Trivia!'
        messaging_client: APIController = bandwidth_client.messaging_client.client
        api_response: ApiResponse = messaging_client.create_message(
            BANDWIDTH_ACCOUNT_ID, message_request)
        message_response: BandwidthMessage = api_response.body
        return 'New Question Generated'

    elif message.text.lower().strip() == 'delete':
        # If user is requesting account deletion - delete db info
        TriviaUser.query.filter_by(phoneNumber=respondents).delete()
        db.session.commit()
        message_request.text = str(
            'Account successfully deleted. '
            'Simply text us again if you\'d like to make a new one!')
        messaging_client: APIController = bandwidth_client.messaging_client.client
        api_response: ApiResponse = messaging_client.create_message(
            BANDWIDTH_ACCOUNT_ID, message_request)
        message_response: BandwidthMessage = api_response.body
        return 'Account Deleted'

    elif message.text.lower().strip() == 'help':
        # Send a help message with the available message commands
        message_request.text = 'Text \'new\' to receive a new question.\n\nText \'delete\' to permanently delete ' \
                               'your account.\n\nYou can respond to multiple choice questions by either responding ' \
                               'with the corresponding letter choice or texting the full answer.\nTrue/False ' \
                               'questions can be answered by responding with either T, F, True, or False.' \
                               '\n\nCurrent Points: ' + str(database_user.points) + '\nMax Points: ' + \
                               str(database_user.maxPoints) + '\nLives Remaining: ' + str(database_user.lives)
        messaging_client: APIController = bandwidth_client.messaging_client.client
        api_response: ApiResponse = messaging_client.create_message(
            BANDWIDTH_ACCOUNT_ID, message_request)
        message_response: BandwidthMessage = api_response.body
        return 'Help is on the way!'

    elif message.text.lower().strip() == database_user.currentAnswer.lower().strip() or message.text.lower().strip() \
            == database_user.currentShortAnswer.lower().strip():
        answer_confirmation_text = 'Correct!'
        # Award points for giving the correct answer
        database_user.points += int(question_difficulty)
        if database_user.points > database_user.maxPoints:
            database_user.maxPoints = int(database_user.points)

        # set the answer field in the database record to match the newly generated answer
        database_user.currentQuestion = question
        database_user.currentAnswer = question_correct_answer
        database_user.currentShortAnswer = question_short_answer
        db.session.commit()

    else:
        if database_user.currentAnswer == '':
            answer_confirmation_text = 'Welcome to Text Trivia!'
        else:
            answer_confirmation_text = 'Incorrect. The correct answer was ' + \
                                       str(database_user.currentAnswer).strip() + '.'
            database_user.lives -= 1
            if database_user.lives == 0:
                # Reset current point streak if user runs out of lives
                database_user.points = 0
                database_user.lives = 5
                answer_confirmation_text = answer_confirmation_text + '\n\nYou are out of lives! ' \
                                                                      'Your points have been reset.'
        database_user.currentQuestion = question
        database_user.currentAnswer = question_correct_answer
        database_user.currentShortAnswer = question_short_answer
        db.session.commit()

    new_message_text = str(
        str(answer_confirmation_text) + '\n\n' + str(question_text) +
        '\n\n\n' + 'Total Points: ' + str(database_user.points) + '\nLives: ' +
        str(database_user.lives) + '\nBest Score: ' +
        str(database_user.maxPoints) +
        '\n\nThanks for playing Text Trivia!\nText \'Help\' for help.')

    # Create and send our message using Bandwidht's API
    message_request.text = new_message_text
    messaging_client: APIController = bandwidth_client.messaging_client.client
    api_response: ApiResponse = messaging_client.create_message(
        BANDWIDTH_ACCOUNT_ID, message_request)
    message_response: BandwidthMessage = api_response.body
    return ''
Exemple #28
0
    def get_messages(self,
                     account_id,
                     message_id=None,
                     source_tn=None,
                     destination_tn=None,
                     message_status=None,
                     error_code=None,
                     from_date_time=None,
                     to_date_time=None,
                     page_token=None,
                     limit=None):
        """Does a GET request to /users/{accountId}/messages.

        Gets a list of messages based on query parameters.

        Args:
            account_id (string): User's account ID
            message_id (string, optional): The ID of the message to search
                for. Special characters need to be encoded using URL encoding
            source_tn (string, optional): The phone number that sent the
                message
            destination_tn (string, optional): The phone number that received
                the message
            message_status (string, optional): The status of the message. One
                of RECEIVED, QUEUED, SENDING, SENT, FAILED, DELIVERED,
                ACCEPTED, UNDELIVERED
            error_code (int, optional): The error code of the message
            from_date_time (string, optional): The start of the date range to
                search in ISO 8601 format. Uses the message receive time. The
                date range to search in is currently 14 days.
            to_date_time (string, optional): The end of the date range to
                search in ISO 8601 format. Uses the message receive time. The
                date range to search in is currently 14 days.
            page_token (string, optional): A base64 encoded value used for
                pagination of results
            limit (int, optional): The maximum records requested in search
                result. Default 100. The sum of limit and after cannot be more
                than 10000

        Returns:
            ApiResponse: An object with the response value as well as other
                useful information such as status codes and headers.
                successful operation

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/users/{accountId}/messages'
        _url_path = APIHelper.append_url_with_template_parameters(_url_path, {
            'accountId': {'value': account_id, 'encode': False}
        })
        _query_builder = self.config.get_base_uri(Server.MESSAGINGDEFAULT)
        _query_builder += _url_path
        _query_parameters = {
            'messageId': message_id,
            'sourceTn': source_tn,
            'destinationTn': destination_tn,
            'messageStatus': message_status,
            'errorCode': error_code,
            'fromDateTime': from_date_time,
            'toDateTime': to_date_time,
            'pageToken': page_token,
            'limit': limit
        }
        _query_builder = APIHelper.append_url_with_query_parameters(
            _query_builder,
            _query_parameters
        )
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'accept': 'application/json'
        }

        # Prepare and execute request
        _request = self.config.http_client.get(_query_url, headers=_headers)
        MessagingBasicAuth.apply(self.config, _request)
        _response = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _response.status_code == 400:
            raise MessagingException('400 Request is malformed or invalid', _response)
        elif _response.status_code == 401:
            raise MessagingException('401 The specified user does not have access to the account', _response)
        elif _response.status_code == 403:
            raise MessagingException('403 The user does not have access to this API', _response)
        elif _response.status_code == 404:
            raise MessagingException('404 Path not found', _response)
        elif _response.status_code == 415:
            raise MessagingException('415 The content-type of the request is incorrect', _response)
        elif _response.status_code == 429:
            raise MessagingException('429 The rate limit has been reached', _response)
        self.validate_response(_response)

        decoded = APIHelper.json_deserialize(_response.text, BandwidthMessagesList.from_dictionary)
        _result = ApiResponse(_response, body=decoded)
        return _result
    def get_query_metadata_for_account(self,
                                       account_id,
                                       mfrom=None,
                                       to=None,
                                       min_start_time=None,
                                       max_start_time=None):
        """Does a GET request to /api/v2/accounts/{accountId}/recordings.

        Returns a list of metadata for the recordings associated with the
        specified account. The list can be filtered by the optional from, to,
        minStartTime, and maxStartTime arguments. The list is capped at 1000
        entries and may be empty if no recordings match the specified
        criteria.

        Args:
            account_id (string): TODO: type description here.
            mfrom (string, optional): TODO: type description here.
            to (string, optional): TODO: type description here.
            min_start_time (string, optional): TODO: type description here.
            max_start_time (string, optional): TODO: type description here.

        Returns:
            list of RecordingMetadataResponse: Response from the API.
                successful operation

        Raises:
            APIException: When an error occurs while fetching the data from
                the remote API. This exception includes the HTTP Response
                code, an error message, and the HTTP body that was received in
                the request.

        """

        # Prepare query URL
        _url_path = '/api/v2/accounts/{accountId}/recordings'
        _url_path = APIHelper.append_url_with_template_parameters(_url_path, {
            'accountId': account_id
        })
        _query_builder = self.config.get_base_uri(Server.VOICEDEFAULT)
        _query_builder += _url_path
        _query_parameters = {
            'from': mfrom,
            'to': to,
            'minStartTime': min_start_time,
            'maxStartTime': max_start_time
        }
        _query_builder = APIHelper.append_url_with_query_parameters(
            _query_builder,
            _query_parameters
        )
        _query_url = APIHelper.clean_url(_query_builder)

        # Prepare headers
        _headers = {
            'accept': 'application/json'
        }

        # Prepare and execute request
        _request = self.config.http_client.get(_query_url, headers=_headers)
        VoiceBasicAuth.apply(self.config, _request)
        _response = self.execute_request(_request)

        # Endpoint and global error handling using HTTP status codes.
        if _response.status_code == 400:
            raise ApiErrorResponseException('Something\'s not quite right... Either your request is invalid or you\'re requesting it at a bad time. Please fix it before trying again.', _response)
        elif _response.status_code == 401:
            raise APIException('Please authenticate yourself.', _response)
        elif _response.status_code == 403:
            raise ApiErrorResponseException('Your credentials are invalid. Please use your API credentials for the Bandwidth Dashboard.', _response)
        elif _response.status_code == 404:
            raise ApiErrorResponseException('The resource specified cannot be found or does not belong to you.', _response)
        elif _response.status_code == 415:
            raise ApiErrorResponseException('We don\'t support that media type. If a request body is required, please send it to us as `application/json`.', _response)
        elif _response.status_code == 429:
            raise ApiErrorResponseException('You\'re sending requests to this endpoint too frequently. Please slow your request rate down and try again.', _response)
        elif _response.status_code == 500:
            raise ApiErrorResponseException('Something unexpected happened. Please try again.', _response)
        self.validate_response(_response)

        decoded = APIHelper.json_deserialize(_response.text, RecordingMetadataResponse.from_dictionary)
        _result = ApiResponse(_response, body=decoded)
        return _result