def stream_audio(self, frames_generator, notification_handler=None, audio_type=None): try: self.refresh_app_token() entity = self._create_audio_query_entity(audio_type) headers = self.create_common_headers() headers['Content-Type'] = audio_type headers['X-Voysis-Entity'] = base64.b64encode( json.dumps(entity).encode("UTF-8")) streaming_url = self.base_url.copy().add(path=['queries']) response = requests.post(str(streaming_url), headers=headers, stream=True, verify=self.check_hostname, timeout=self.timeout, data=frames_generator) if response.status_code == 200: query = response.json() self.current_conversation_id = query['conversationId'] self._update_current_context(query) notification_handler('query_complete') return query else: raise client.ClientError( 'Request failed with status code {}'.format( response.status_code)) except OSError as error: msg = error.strerror if not msg: msg = str(error) raise client.ClientError(msg) except (HTTPError, UrlLib3HTTPError) as error: raise client.ClientError(str(error))
def stream_audio(self, frames_generator, notification_handler=None, audio_type=None): try: if audio_type is not None: self._audio_type = audio_type self._complete_reason = None self._error = None self._notification_handler = notification_handler self.connect() self.refresh_app_token() create_entity = self._create_audio_query_entity() # self._event.clear() self.send_request( '/queries', create_entity, call_on_complete=self._update_current_conversation) # self._wait_for_event('query creation') self._event.clear() self.send_audio(frames_generator) self._wait_for_event('query completion') completed_query = self._completed_query self._completed_query = None if completed_query: self._update_current_context(completed_query) return completed_query else: raise client.ClientError("Query failed {}".format( self._complete_reason)) except OSError as error: raise client.ClientError(error.strerror) except websocket.WebSocketConnectionClosedException as error: # This exception typically happens when we try to continue # streaming after the server side has shut down the socket # due to an error condition. if self._error: raise self._error else: raise error except websocket.WebSocketException as error: raise client.ClientError(str(error)) finally: self._notification_handler = None
def execute_request(self, frames_generator=None, notification_handler=None, entity=None): try: self._completion_gate.reset( notification_handler=notification_handler) self.connect() self.refresh_app_token() self.send_request( '/queries', entity, call_on_complete=self._update_current_conversation) self._completion_gate.event.clear() if frames_generator is not None: self.send_audio(frames_generator) if not self._completion_gate.event.wait(): raise client.ClientError( "Timed out waiting on query completion") if self._completion_gate.check_is_complete(): self._update_current_context(self._completion_gate.entity) return self._completion_gate.entity else: raise client.ClientError( "Unknown error waiting for query completion") except OSError as error: raise client.ClientError(error.strerror) except websocket.WebSocketConnectionClosedException as error: # This exception typically happens when we try to continue # streaming after the server side has shut down the socket # due to an error condition. Calling check will cause the # error set by on_ws_error to be raised, if any. self._completion_gate.check_is_complete() raise error except websocket.WebSocketException as error: raise client.ClientError(str(error)) finally: self._completion_gate.reset()
def set_error(self, error: Any) -> None: """ Set this completion gate's final status to error. The threading event will be set so any threads waiting on the gate's final state will be notified. The gate's notification handler, if any, will be called with ``COMPLETE_ERROR``. :param error: The error to report to the client. :return: None """ self._reason = COMPLETE_ERROR if isinstance(error, client.ClientError): self._entity = error else: self._entity = client.ClientError(error) if self._notification_handler: self._notification_handler(self._reason) self._event.set()
def on_ws_message(self, web_socket, message): json_msg = json.loads(message) if 'response' == json_msg['type']: if int(json_msg['responseCode']) > 299: self._error = client.ClientError( "Request {requestId} failed with status code {responseCode}: {responseMessage}" .format(**json_msg)) try: future = self._response_futures.pop(json_msg['requestId']) future.set(json_msg['responseCode'], response_message=json_msg['responseMessage'], response_entity=json_msg['entity']) except KeyError: pass elif 'notification' == json_msg['type']: notification_type = json_msg['notificationType'] if 'query_complete' == notification_type: self._completed_query = json_msg['entity'] self._update_state(notification_type, 'vad_stop' != notification_type)
def _wait_for_event(self, message): if not self._event.wait(self.timeout): raise client.ClientError("Timed out waiting on " + message) if self._error: raise self._error