def speak(): errors = [] if 'text' not in request.json: errors.append(dict(MissingParameterException('text'))) if 'language' not in request.json: errors.append(dict(MissingParameterException('language'))) if errors: return jsonify({'errors': errors}), 400 text = request.json['text'] language = request.json['language'] if language not in LANGUAGES_CODE: return jsonify({'errors': [dict(BadParameterException('language', valid_values=LANGUAGES_CODE))]}), 400 try: res = ibm_send_request(text, language) except (InvalidCredentialsException, ExternalAPIException) as e: return jsonify({'errors': [dict(e)]}), e.status_code except Exception as e: logger.error(e) api_e = APIException() return jsonify({'errors': [dict(api_e)]}), api_e.status_code return Response(res, mimetype="audio/wav", status=200)
def intent(): errors = [] if request.json: if 'text' not in request.json: errors.append(dict(MissingParameterException('text'))) if errors: return jsonify({'errors': errors}), 400 text = request.json['text'] language = request.json.get('language') if language: if language not in LANGUAGES_CODE: return jsonify({ 'errors': [ dict( BadParameterException('language', valid_values=LANGUAGES_CODE)) ] }), 400 try: res = recast_send_request_intent(text, language) return jsonify(res['results']), 200 except InvalidCredentialsException as e: return jsonify({'errors': [dict(e)]}), e.status_code except ExternalAPIException as e: return jsonify({'errors': [dict(e)]}), e.status_code except Exception as e: logger.error(e) return jsonify({'errors': [dict(APIException('nlp_intent'))]}), 500 else: errors.append(dict(APIException('no_content'))) return jsonify({'errors': errors}), 400
def recognize(): errors = [] if 'audio' not in request.files: errors.append(dict(MissingParameterException('audio'))) if 'language' not in request.form: errors.append(dict(MissingParameterException('language'))) if errors: return jsonify({'errors': errors}), 400 file = request.files['audio'] file_content = file.read() language = request.form['language'] if language not in LANGUAGES_CODE: return jsonify({ 'errors': [ dict( BadParameterException('language', valid_values=LANGUAGES_CODE)) ] }), 400 try: res = google_speech_send_request(file_content, language) except (OperationFailedException, BadParameterException) as e: logger.error(e) return jsonify({'errors': [dict(e)]}), e.status_code return jsonify(res), 200
def test_exception_bad_parameter_exception(): expected_result = {'code': 'bad_parameter', 'msg': 'test is not correct.'} with pytest.raises(BadParameterException) as e: raise BadParameterException(parameter='test') e = e.value assert e.status_code == 400 assert sorted(e.to_dict().items()) == sorted(expected_result.items()) expected_result = { 'code': 'bad_parameter', 'msg': 'test is not correct. Valid values are: test1, test2' } with pytest.raises(BadParameterException) as e: raise BadParameterException(parameter='test', valid_values=['test1', 'test2']) e = e.value assert e.status_code == 400 assert sorted(e.to_dict().items()) == sorted(expected_result.items())
def google_news_get_news(source='google-news-fr'): res = requests.get('https://newsapi.org/v2/top-headlines', params={ 'sources': source, 'apiKey': token }) print(res.content) if res.status_code == 200: return res.json() elif res.status_code == 400: raise BadParameterException(source) else: raise ExternalAPIException(api_name='Google News', description='http_code:{}'.format( res.status_code))
def test_recognize_bad_language(mock_google_speech_send_request, client, google_request): res = client.post( url_for('stt_google.recognize'), content_type='multipart/form-data', data={ 'language': 'xx-XX', 'audio': (io.BytesIO(google_request['file']), 'audio.wav') } ) expected_result = {'errors': [dict(BadParameterException('language', valid_values=LANGUAGES_CODE))]} assert res.status_code == 400 assert sorted(json.loads(res.data).items()) == sorted(expected_result.items()) assert mock_google_speech_send_request.call_count == 0
def test_intent_bad_language(mock_recast_send_request_intent, client, recast_intent_request): res = client.post(url_for('nlp_recast.intent'), content_type='application/json', data=json.dumps({ 'text': recast_intent_request['text'], 'language': 'xx-XX' })) expected_result = { 'errors': [dict(BadParameterException('language', valid_values=LANGUAGES_CODE))] } assert res.status_code == 400 assert sorted(json.loads(res.data).items()) == sorted( expected_result.items()) assert mock_recast_send_request_intent.call_count == 0
def test_recognize_audio_corrupted(mock_recognize, google_request, client, corrupted_audio): mock_recognize.side_effect = RetryError('mock') res = client.post( url_for('stt_google.recognize'), content_type='multipart/form-data', data={ 'language': google_request['language'], 'audio': (io.BytesIO(corrupted_audio), 'audio.wav') } ) expected_result = { 'errors': [ dict(BadParameterException('audio', ['WAV', '16 bits', 'Mono', '44100Hz', '<1min'])) ] } assert res.status_code == 422 assert sorted(json.loads(res.data).items()) == sorted(expected_result.items()) assert mock_recognize.call_count == 1
def google_speech_send_request(content, language): audio = types.RecognitionAudio(content=content) config = types.RecognitionConfig( encoding=enums.RecognitionConfig.AudioEncoding.LINEAR16, language_code=language) try: response = speech_client.recognize(config, audio) return { 'text': response.results[0].alternatives[0].transcript, 'confidence': round(float(response.results[0].alternatives[0].confidence), 4) } except RetryError as e: print('{} : {}'.format(type(e).__name__, e)) raise BadParameterException( 'audio', ['WAV', '16 bits', 'Mono', '44100Hz', '<1min']) except Exception as e: raise OperationFailedException from e
def memory(): errors = [] if request.json: if 'field' not in request.json: errors.append(dict(MissingParameterException('field'))) if 'user_id' not in request.json: errors.append(dict(MissingParameterException('user_id'))) if errors: return jsonify({'errors': errors}), 400 field = request.json['field'] if field not in SUPPORTED_FIELDS: return jsonify({ 'errors': [ dict( BadParameterException('field', valid_values=SUPPORTED_FIELDS)) ] }), 400 value = request.json.get('value') user_id = request.json['user_id'] try: res = recast_send_request_memory(field, user_id, value) return jsonify(res['results']), 200 except InvalidCredentialsException as e: return jsonify({'errors': [dict(e)]}), e.status_code except ExternalAPIException as e: return jsonify({'errors': [dict(e)]}), e.status_code except Exception as e: logger.error(e) return jsonify({ 'errors': [dict(APIException('nlp_memory'.format(type(e).__name__, e)))] }), 500 else: errors.append(dict(APIException('no_content'))) return jsonify({'errors': errors}), 400
def test_memory_bad_field(mock_recast_send_request_memory, client, recast_memory_request, recast_memory_response): mock_recast_send_request_memory.return_value = recast_memory_response res = client.post(url_for('nlp_recast.memory'), content_type='application/json', data=json.dumps({ 'field': 'xX-yY-zZ', 'value': recast_memory_request['value'], 'user_id': recast_memory_request['user_id'], })) expected_result = { 'errors': [dict(BadParameterException('field', valid_values=SUPPORTED_FIELDS))] } assert res.status_code == 400 assert sorted(json.loads(res.data).items()) == sorted( expected_result.items()) assert mock_recast_send_request_memory.call_count == 0
def test_converse_bad_language(mock_recast_send_request_dialog, client, converse_text_request, converse_audio_request): res = client.post(url_for('converse.conversation-text'), content_type='application/json', data=json.dumps({ 'text': converse_text_request['text'], 'user_id': converse_text_request['user_id'], 'language': 'xx-XX' })) expected_result = { 'errors': [dict(BadParameterException('language', valid_values=LANGUAGES_CODE))] } print(res.data) assert res.status_code == 422 assert sorted(json.loads(res.data).items()) == sorted( expected_result.items()) res = client.post(url_for('converse.conversation-audio'), content_type='multipart/form-data', data={ 'audio': (io.BytesIO(converse_audio_request['audio']), 'audio.wav'), 'language': 'xx-XX', 'user_id': converse_audio_request['user_id'] }) assert res.status_code == 422 assert sorted(json.loads(res.data).items()) == sorted( expected_result.items()) assert mock_recast_send_request_dialog.call_count == 0
def conversation(want): output = {} skipping_nlp = False user_id = None message = None intent = None text = None language = None input_type, errors, code = check_request(request) if errors: return jsonify({'errors': errors}), code # Case: input is audio if input_type == 'audio': if 'user_id' in request.form: user_id = request.form['user_id'] audio = request.files['audio'] language = request.form['language'] if language not in LANGUAGES_CODE: return jsonify({'errors': [dict(BadParameterException('language', valid_values=LANGUAGES_CODE))]}), BadParameterException.status_code try: file_content = audio.read() except Exception: return jsonify({'errors': [dict(BadParameterException('audio'))]}), BadParameterException.status_code try: res = stt.google_speech_send_request(file_content, language) text = res["text"] stt_confidence = res["confidence"] output['input'] = text output['stt_confidence'] = stt_confidence except OperationFailedException as e: logger.error(e) message = CUSTOM_MESSAGES[SIMPLIFIED_LANGUAGES_CODE[language]]["not-heard"] intent = DEFAULT_INTENT skipping_nlp = True except Exception as e: logger.error(e) return jsonify({'errors': [dict(ExternalAPIException('Google'))]}), ExternalAPIException.status_code # Case: input is text elif input_type == 'text': user_id = request.json.get('user_id') # print(user_id) text = request.json['text'] language = request.json['language'] output['input'] = text if language not in LANGUAGES_CODE: return jsonify({'errors': [dict(BadParameterException('language', valid_values=LANGUAGES_CODE))]}), BadParameterException.status_code if not skipping_nlp: # Analyze the text try: res_nlp = nlp.recast_send_request_dialog(text, user_id, SIMPLIFIED_LANGUAGES_CODE[language]) output['nlp'] = res_nlp print(res_nlp) if not res_nlp['results']['nlp']['intents']: intent = DEFAULT_INTENT else: intent = res_nlp['results']['nlp']['intents'][0]['slug'] if not res_nlp['results']['messages']: message = CUSTOM_MESSAGES[SIMPLIFIED_LANGUAGES_CODE[language]]["not-understand"] else: message = res_nlp['results']['messages'][0]['content'] except (InvalidCredentialsException, ExternalAPIException) as e: return jsonify({'errors': [dict(e)]}), e.status_code except Exception as e: logger.error(e) return jsonify({'errors': [dict(APIException(code='nlp_error', msg=str(e)))]}), APIException.status_code # Check special intents try: spec_message = check_special_intent(intent, res_nlp['results'], SIMPLIFIED_LANGUAGES_CODE[language]) if spec_message: message = spec_message except ExternalAPIException as e: return jsonify({'errors': [dict(e)]}), e.status_code except Exception as e: logger.error(e) return jsonify({'errors': [dict(APIException(code='services_error', msg=str(e)))]}), APIException.status_code # Regroup information output['message'] = message output['intent'] = intent # Send the result if want == 'text': return jsonify(output), 200 elif want == 'audio': try: res_tts = tts.ibm_send_request(message, language) except (InvalidCredentialsException, ExternalAPIException) as e: return jsonify({'errors': [dict(e)]}), e.status_code except Exception as e: logger.error(e) api_e = APIException(code='tts_error', msg=str(e)) return jsonify({'errors': [dict(api_e)]}), api_e.status_code response = Response(res_tts, mimetype="audio/wav", status=200) response.headers['JSON'] = json.dumps(output) return response else: # Impossible ! return jsonify({'errors': [dict(APIException(code='invalid_output_format_requested'))]}), APIException.status_code