def testing_adding_corpus2(mock): mock.return_value = PosixPath('blah') mock.exists().return_value = True mock.is_file().return_value = False with pytest.raises(FileExistsError, match="The path of the file is invalid"): WatsonSTT(url=url).add_corpus("blah")
def test_create_model(mock, error_codes): if error_codes == 201: mock.return_value.status_code = 201 expected_response = json.dumps({'customization_id': '1234'}) mock.return_value.text = expected_response response = WatsonSTT(url=url).create_model(name="Testing Model", descr="From test") assert response == '1234' # testing if the API messes up does not have a 'customization_id' missing_response = json.dumps({'blah': 'blah'}) mock.return_value.text = missing_response with pytest.raises( Exception, match="The Watson STT request failed. Please try again."): WatsonSTT(url).create_model(name="Testing", descr="from test")
def runner(self): """ The runner parses the options selected and then calls the backend functions from WatsonSTT class """ try: account_details = prompt(self.account_details(), style=custom_style_2) if account_details['watson_stt_url'] == "None": print() print("Attempting to read in url from configuration file") try: path = Path('./keys/conf.ini').resolve() config = ConfigParser() config.read(path) self.url = config['URL']['WATSON_STT_URL'] print("Succesfully read URL.") print() except: print("Uh oh! We failed to read the URL from the configuration file.") raise ValueError("Failure to read URL from conf.ini file") else: url = account_details['watson_stt_url'] self.url = url self._save_url(self.url) if account_details['watson_stt_api_key'] == "None": print("Attempting to read in API key from configuration file") try: path = Path('./keys/conf.ini').resolve() config = ConfigParser() config.read(path) self.api_key = config['API_KEY']['WATSON_STT_API'] print("Succesfully read in API key.") print() except: print("Uh oh! We failed to read the API Key from the configuration file.") raise ValueError("Failure to read API key from conf.ini file") else: api_key = account_details['watson_stt_api_key'] self.api_key = api_key self._save_api_key(api_key) answers = prompt(self.main_questions(), style=custom_style_2) model_options = answers['custom_models_options'] for model_option in model_options: if 'Train' in model_option: # ask train questions train = prompt(self.train_questions(), style=custom_style_2) model_name = train['model_name'] model_descr = train['model_description'] oov_file_path = train['oov_file_path'] try: stt = WatsonSTT(url=self.url) stt.create_model(name=model_name, descr=model_descr) stt.add_corpus(oov_file_path) stt.training() except Exception as e: print(e) if 'Update'in model_option: update = prompt(self.update_questions(), style=custom_style_2) model_customization_id = update['customization_id'] oov_file_path = update['oov_file_path'] try: stt = WatsonSTT(url=self.url, customization_id=model_customization_id) stt.add_corpus(corpus_path=oov_file_path) stt.training() except Exception as e: print(e) if 'Evaluate' in model_option: model_id, evaluate_answers = self.evaluate_questions() evaluate_models = prompt(evaluate_answers, style=custom_style_2) path_to_audio_file = evaluate_models['audio_file'] evaluate_models = evaluate_models['models_evaluate'] custom_ids = [model_id[eval_model] for eval_model in evaluate_models] for index, id in enumerate(custom_ids): stt = WatsonSTT(url=self.url, customization_id=id) try: results = stt.transcribe(path_to_audio_file) print() print("*" * 60) print(f"Transcription Results from {evaluate_models[index]}:") pprint(results) print() print("*" * 60) print() except Exception as e: print("*" * 60) print() print(f"Transcribing model {evaluate_models[index]} failed.") print(e) print("*" * 60) print() if 'See Available Models' in model_option: models = WatsonSTT.all_model_status(url=self.url, api_key=self.api_key) pprint(models) # check if the model can be deleted # error of the model should be 409 if 'Delete' in model_option: delete_options = prompt(self.delete(), style=custom_style_2) delete_options = delete_options['delete_all'].strip().lower() if delete_options in ('y', 'yes'): clean_up.clean_up(url=self.url, customization_ids=['all']) elif delete_options in ('n', 'no'): models_id, models_delete = self._delete_specific_models() selected_models = prompt(models_delete, style=custom_style_2) models_to_delete = selected_models['models_to_delete'] custom_ids_del_models = [models_id[del_model] for del_model in models_to_delete] # delete the models clean_up.clean_up(self.url, custom_ids_del_models) else: print("Only \'yes\' and \'no\' inputs allowed") raise KeyboardInterrupt except KeyboardInterrupt: print("Action Cancelled")
def test_training_no_customization_id(): with pytest.raises(ValueError, match="No customization id is provided!"): WatsonSTT(url).training()
def test_invalid_create_model_params(): with pytest.raises(TypeError, match=r".* 'name' .*"): WatsonSTT(url).create_model(name=InvalidType(), descr="valid") with pytest.raises(TypeError, match=r".* 'descr' .*"): WatsonSTT(url).create_model(name="valid", descr=InvalidType())
def main(): """Entry point of the CLI. The program will accept either a "--visual" flag, where it then kicks out to the visual CLI. Otherwise, it will accept name, descr, url, oov_file_path, verbose, delete, eval, or audio_file flags. Passing certain combination of these flags will trigger different actions such as train, evaluate, or delete. Args: --visual: kick of the visual CLI. At this point, the control of the program is handed over to the visual.py file --url: the url of the instance --name: name of the model --descr: the description of the model --oov_file_path: the filepath of the grammar, vocabulary, or corpus used to train the model --eval: transcribe a model --verbose: list out the models --audio_file: path to the audio file Returns: None """ # setting up the command line argparser = argparse.ArgumentParser() argparser.add_argument( '--visual', help="Run CLI in visual mode. All other flags passed are ignored", action="store_true") argparser.add_argument('--name', help="Name of the model") argparser.add_argument('--descr', help="A short description of the custom model") argparser.add_argument('--url', help="This is the URL of the Watson STT model. \ Found on the start page of the Watson STT tooling." ) argparser.add_argument('--oov_file_path', help="The path of the out-of-vocabulary \ file (the corpus, words, or grammar)" ) argparser.add_argument('-v', '--verbose', '--list_models', help="Shows you all \ of the models trained on this account" , \ action="store_true") argparser.add_argument( '--delete', nargs='+', help="Pass the customization id of the models to delete") argparser.add_argument( '--eval', help="Evaluate the trained model against an audio-file. \ \nPass in the \'customization_id\' of the model or \ pass \'latest\' to train the latest trained model. \ \nThe \'audio_file\' flag must be set as well!" ) argparser.add_argument('--audio_file', help="The path of the audio file to transcribe.") args = argparser.parse_args() visual = args.visual name = args.name descr = args.descr url = args.url file_path = args.oov_file_path verbose = args.verbose delete = args.delete evaluate = args.eval audio_file = args.audio_file if visual: VisualSTT().runner() else: if url is None: raise Exception("Must pass URL") # kick of training if name and descr and url and file_path: custom_stt = WatsonSTT(url=url) custom_stt.create_model(name=name, descr=descr) custom_stt.add_corpus(file_path) custom_stt.training() # just add the corpus # @TODO: how to create a model and train with an existing corpus? # @TODO: is this feature even neccesary? if url and file_path and name is None is file_path is None: print("Adding corpus...") # @TODO: training a model with an existing uploaded corpus custom_stt = WatsonSTT(url=url) custom_stt.add_corpus(file_path) print("Finished adding corpus") # print out the models if url and verbose: print("Retrieving Models...") model_status(url) if url and evaluate and audio_file: # pass in customization id print("Checking audio file...") path = Path(audio_file) if not path.exists() and not path.is_file(): raise FileExistsError("Cannot find audio file") if evaluate == "latest": models = model_status(url, print=0) models = models['customizations'] if len(models) == 0: print( "You do not have any trained models. Please create and train a model before evaluating." ) return # convert the date string into date object for model in models: model['created'] = _to_date(model['created']) models = sorted(models, key=itemgetter('created'), reverse=True) evaluate = models[0]['customization_id'] print("Transcribing the audio file...") custom_stt = WatsonSTT(url=url, customization_id=evaluate) results = custom_stt.transcribe(audio_file) print("Transcribing finished") print() pprint(results) if url and delete: clean_up.clean_up(url, delete)