From e1e340aaf8bbc66543ff571b982547db807f705c Mon Sep 17 00:00:00 2001 From: kingslayerrq Date: Sun, 3 Dec 2023 20:08:19 -0500 Subject: [PATCH] lint/black mlc --- .../machine_learning_client.py | 98 +++++++------- machine-learning-client/tests/ml_tests.py | 128 +++++++++++------- 2 files changed, 131 insertions(+), 95 deletions(-) diff --git a/machine-learning-client/machine_learning_client.py b/machine-learning-client/machine_learning_client.py index 5a67b14..00e0ec2 100644 --- a/machine-learning-client/machine_learning_client.py +++ b/machine-learning-client/machine_learning_client.py @@ -3,15 +3,15 @@ to text transcription and analysis of audio transcription """ -import sys -import pyaudio -import pymongo -import pyaudio + import os +import pyaudio + + from pymongo import MongoClient import speech_recognition as sr from flask_cors import CORS -from flask import Flask, request, jsonify, send_from_directory +from flask import Flask, request, jsonify from pydub import AudioSegment app = Flask(__name__) @@ -22,13 +22,14 @@ client = MongoClient("mongodb://mongodb:27017/") db = client["ml_databse"] collection = db["transcription"] - + app.config["UPLOAD_FOLDER"] = "uploads" os.makedirs(app.config["UPLOAD_FOLDER"], exist_ok=True) PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) pa = pyaudio.PyAudio() + def add_transcription_mongo(transcription, grade_report): """ Save transcription to MongoDB @@ -38,9 +39,10 @@ def add_transcription_mongo(transcription, grade_report): result = collection.insert_one(data) print(f"Transcription saved to MongoDB with ID: {result.inserted_id}") - except Exception as e: + except Exception as e: # pylint: disable=broad-exception-caught print(f"Error saving transcription to MongoDB: {e}") + def audio_to_text(audio_file_string): """Function for converting audio file to text transcription""" r = sr.Recognizer() @@ -58,22 +60,20 @@ def audio_to_text(audio_file_string): print("success!! we transcribed it") return transcription -def grade_transcription(transcription_text): + +def grade_transcription(transcription_text): # pylint: disable=too-many-branches,too-many-statements """ - Function to generate a page giving a break down and grade of an audio transcript someone had just recorded + Function to generate a page giving a break down and grade of an audio transcript someone had just recorded # pylint: disable=line-too-long """ - + grade = 0 filler_words = 0 buzz_words = 0 - - """filler_words += my_transcript.find()""" filler_words += transcription_text.lower().count("uh") filler_words += transcription_text.lower().count("um") filler_words += transcription_text.lower().count("ah") filler_words += transcription_text.lower().count("like") filler_words += transcription_text.lower().count("er") - buzz_words += transcription_text.lower().count("education") buzz_words += transcription_text.lower().count("major") buzz_words += transcription_text.lower().count("college") @@ -84,33 +84,27 @@ def grade_transcription(transcription_text): buzz_words += transcription_text.lower().count("certificate") buzz_words += transcription_text.lower().count("qualification") buzz_words += transcription_text.lower().count("work") - buzz_words += transcription_text.lower().count("interest") + buzz_words += transcription_text.lower().count("interest") buzz_words += transcription_text.lower().count("develop") buzz_words += transcription_text.lower().count("fulfill") buzz_words += transcription_text.lower().count("refine") - print("this value of filler word: ", filler_words) print("this value of buzz word: ", buzz_words) - fw_breakdown = "" bz_breakdown = "" grade_analysis = "" - - if buzz_words == 0: - bz_breakdown = "You did not use any buzz words. When answering this question, try to talk about your education, work experiences, major, or any jobs you had." + bz_breakdown = "You did not use any buzz words. When answering this question, try to talk about your education, work experiences, major, or any jobs you had." # pylint: disable=line-too-long elif 0 < buzz_words <= 5: - bz_breakdown = f"You used {buzz_words} buzz words. A decent answer, but you can improve. Try to find more things to say about yourself professionally." + bz_breakdown = f"You used {buzz_words} buzz words. A decent answer, but you can improve. Try to find more things to say about yourself professionally." # pylint: disable=line-too-long else: - bz_breakdown = f"You used {buzz_words} buzz words. The topics of your answer are acceptable. Make sure to " - + bz_breakdown = f"You used {buzz_words} buzz words. The topics of your answer are acceptable. Make sure to " # pylint: disable=line-too-long if filler_words == 0: - fw_breakdown = "You did not use any filler words. Or there was a problem with the audio transcript. Either way, remember to talk confidently and at a good pace." + fw_breakdown = "You did not use any filler words. Or there was a problem with the audio transcript. Either way, remember to talk confidently and at a good pace." # pylint: disable=line-too-long elif 0 < filler_words <= 5: - fw_breakdown = f"You used {filler_words} filler words. From here, you just need to practice your answer until it comes out naturally. Make sure to keep relaxed." + fw_breakdown = f"You used {filler_words} filler words. From here, you just need to practice your answer until it comes out naturally. Make sure to keep relaxed." # pylint: disable=line-too-long else: - fw_breakdown = f"You used {filler_words} filler words. When giving your answer, try speaking slower and more clearly. Don't confuse yourself by thinking too far ahead." - + fw_breakdown = f"You used {filler_words} filler words. When giving your answer, try speaking slower and more clearly. Don't confuse yourself by thinking too far ahead." # pylint: disable=line-too-long grade = (buzz_words * 3) - filler_words print(grade) if grade > 20: @@ -118,40 +112,44 @@ def grade_transcription(transcription_text): elif grade < 0: grade = 0 if grade == 0: - grade_analysis = f"Your grade is {grade}/20. You should rethink your answer to be more focused and clearly thought out." + grade_analysis = f"Your grade is {grade}/20. You should rethink your answer to be more focused and clearly thought out." # pylint: disable=line-too-long elif 0 < grade <= 5: - grade_analysis = f"Your grade is {grade}/20. Refine your answer by reflecting on your education, work experience, and relevant info." + grade_analysis = f"Your grade is {grade}/20. Refine your answer by reflecting on your education, work experience, and relevant info." # pylint: disable=line-too-long elif 5 < grade <= 10: - grade_analysis = f"Your grade is {grade}/20. You're answer fulfills some of the necessary buzz words. If you have any more relevant data or ways to improve your speech, do so." + grade_analysis = f"Your grade is {grade}/20. You're answer fulfills some of the necessary buzz words. If you have any more relevant data or ways to improve your speech, do so." # pylint: disable=line-too-long elif 10 < grade <= 15: - grade_analysis = f"Your grade is {grade}/20. You gave a very good response. Everything beyond this is fine tuning your response to the interviewer." + grade_analysis = f"Your grade is {grade}/20. You gave a very good response. Everything beyond this is fine tuning your response to the interviewer." # pylint: disable=line-too-long else: - grade_analysis = f"Your grade is {grade}/20. This should be your go to answer, but it all depends on the interviewer. This answer should could out naturally and be your basis." - + grade_analysis = f"Your grade is {grade}/20. This should be your go to answer, but it all depends on the interviewer. This answer should could out naturally and be your basis." # pylint: disable=line-too-long grade_report = { "filler_words": fw_breakdown, "buzz_words": bz_breakdown, - "grade_analysis": grade_analysis + "grade_analysis": grade_analysis, } - print(fw_breakdown) print(bz_breakdown) print(grade_analysis) return grade_report + @app.route("/analyzeAudio", methods=["POST"]) -def analyze_Audios(): +def analyze_Audios(): # pylint: disable=invalid-name """ Endpoint to receive and analyze audio file """ try: if "audio" not in request.files: - return jsonify({"status": "error", "message": "No audio file provided"}), 400 - + return ( + jsonify({"status": "error", "message": "No audio file provided"}), + 400, + ) + audio_file = request.files["audio"] # Delete existing files if they exist - existing_audio_path = os.path.join(app.config["UPLOAD_FOLDER"], "user_audio.wav") + existing_audio_path = os.path.join( + app.config["UPLOAD_FOLDER"], "user_audio.wav" + ) if os.path.exists(existing_audio_path): os.remove(existing_audio_path) @@ -174,20 +172,24 @@ def analyze_Audios(): print(true_audio_path) # Call your functions from ml.py to process the audio print("calling audio to text method") - transcription = audio_to_text(true_audio_path_str) + transcription = audio_to_text(true_audio_path_str) print(transcription) - print("calling grade to text method") - gradedTranscription = grade_transcription(transcription) - add_transcription_mongo(transcription, gradedTranscription) - + print("calling grade to text method") + graded_transcription = grade_transcription(transcription) + add_transcription_mongo(transcription, graded_transcription) print("we did it baby") - return jsonify({"status": "success", "message": "Audio analysis completed"}), 200 - - except Exception as e: - return jsonify({"status": "error", "message": f"An error occurred: {str(e)}"}), 500 + return ( + jsonify({"status": "success", "message": "Audio analysis completed"}), + 200, + ) + + except Exception as e: # pylint: disable=broad-exception-caught + return ( + jsonify({"status": "error", "message": f"An error occurred: {str(e)}"}), + 500, + ) if __name__ == "__main__": app.run(host="0.0.0.0", port=int(os.getenv("PORT", "5001")), debug=True) - diff --git a/machine-learning-client/tests/ml_tests.py b/machine-learning-client/tests/ml_tests.py index 3fb4e6b..6da3dae 100644 --- a/machine-learning-client/tests/ml_tests.py +++ b/machine-learning-client/tests/ml_tests.py @@ -1,54 +1,80 @@ """ tests for machine-learning-client """ -import machine_learning_client as ML import os +import machine_learning_client as ML # pylint: disable=import-error import pytest -from flask import Flask -from flask_cors import CORS -from flask import Flask, request, jsonify -from flask.testing import FlaskClient -from flask_cors import CORS -from pytest_flask import fixtures -from machine_learning_client import audio_to_text, grade_transcription, add_transcription_mongo + + + + + + + + + # Mocking dependencies and functions @pytest.fixture def mock_dependencies(monkeypatch): - monkeypatch.setattr("machine_learning_client.audio_to_text", lambda *args, **kwargs: "mocked_transcription") - monkeypatch.setattr("machine_learning_client.grade_transcription", lambda *args, **kwargs: "mocked_grade") - monkeypatch.setattr("machine_learning_client.add_transcription_mongo", lambda *args, **kwargs: None) + """Setup Mock""" + monkeypatch.setattr( + "machine_learning_client.audio_to_text", + lambda *args, **kwargs: "mocked_transcription", + ) + monkeypatch.setattr( + "machine_learning_client.grade_transcription", + lambda *args, **kwargs: "mocked_grade", + ) + monkeypatch.setattr( + "machine_learning_client.add_transcription_mongo", lambda *args, **kwargs: None + ) + # Create a fixture for the Flask application with CORS enabled @pytest.fixture def client(): - with ML.app.test_client() as client: + """Create a fixture for the Flask application with CORS enabled""" + with ML.app.test_client() as client: # pylint: disable=redefined-outer-name yield client + # Test the route handler with a valid audio file -def test_analyze_audios_valid_audio(client): +def test_analyze_audios_valid_audio(client): # pylint: disable=redefined-outer-name + """Test the route handler with a valid audio file""" audio_file_path = os.path.join(os.path.dirname(__file__), "test_audio.webm") print(audio_file_path) with open(audio_file_path, "rb") as audio_file: - response = client.post("/analyzeAudio", data={"audio": (audio_file, "test_audio.webm")}) + response = client.post( + "/analyzeAudio", data={"audio": (audio_file, "test_audio.webm")} + ) assert response.status_code == 200 assert response.json == {"status": "success", "message": "Audio analysis completed"} + # Test the route handler without including an audio file -def test_analyze_audios_no_audio_file(client): +def test_analyze_audios_no_audio_file(client): # pylint: disable=redefined-outer-name + """Test the route handler without including an audio file""" response = client.post("/analyzeAudio") assert response.status_code == 400 assert response.json == {"status": "error", "message": "No audio file provided"} + # Test the route handler with an exception during audio processing -def test_analyze_audios_exception(client, monkeypatch): - monkeypatch.setattr("machine_learning_client.audio_to_text", lambda *args, **kwargs: Exception("Mocked exception")) +def test_analyze_audios_exception(client, monkeypatch): # pylint: disable=redefined-outer-name + """Test the route handler with an exception during audio processing""" + monkeypatch.setattr( + "machine_learning_client.audio_to_text", + lambda *args, **kwargs: Exception("Mocked exception"), + ) audio_file_path = os.path.join(os.path.dirname(__file__), "test_audio.webm") with open(audio_file_path, "rb") as audio_file: - response = client.post("/analyzeAudio", data={"audio": (audio_file, "test_audio.webm")}) + response = client.post( + "/analyzeAudio", data={"audio": (audio_file, "test_audio.webm")} + ) assert response.status_code == 500 assert response.json["status"] == "error" @@ -56,14 +82,16 @@ def test_analyze_audios_exception(client, monkeypatch): # Asserting that the error message starts with "An error occurred:" assert response.json["message"].startswith("An error occurred:") + class Tests: """Tests class for ml_tests.py""" + def test_audio_text_conversion(self): """testing audio_to_text function in ML with valid audiofile as input""" - PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) + project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) tests_path = "tests" file_name = "richard.aiff" - file_path = os.path.join(PROJECT_ROOT, tests_path, file_name) + file_path = os.path.join(project_root, tests_path, file_name) print(file_path) actual = ML.audio_to_text(file_path) assert isinstance( @@ -72,45 +100,51 @@ def test_audio_text_conversion(self): assert ( actual.lower() == "my name is richard" ), f"Expected the converted audio to be 'my name is richard'. Instead it returned {actual}" - - - def test_grade_transcription_good(self): - """testing grade_transcription function in ML with a recording of all filler && buzz words""" - PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) + """testing grade_transcription function in ML with a recording of all filler && buzz words""" # pylint: disable=line-too-long + project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) tests_path = "tests" file_name = "filler.aiff" - file_path = os.path.join(PROJECT_ROOT, tests_path, file_name) + file_path = os.path.join(project_root, tests_path, file_name) actual = ML.grade_transcription(ML.audio_to_text(file_path)) - assert isinstance(actual, dict), f"Expected grade_transcription to return a dict. Instead it returned a {actual}" - assert (actual == {"filler_words": "You used 7 filler words. When giving your answer, try speaking slower and more clearly. Don't confuse yourself by thinking too far ahead.", - "buzz_words": "You used 14 buzz words. The topics of your answer are acceptable. Make sure to ", - "grade_analysis": "Your grade is 20/20. This should be your go to answer, but it all depends on the interviewer. This answer should could out naturally and be your basis."} - ), f"Expected a 20 grade report. Instead it returned {actual}" - + assert isinstance( + actual, dict + ), f"Expected grade_transcription to return a dict. Instead it returned a {actual}" + assert actual == { + "filler_words": "You used 7 filler words. When giving your answer, try speaking slower and more clearly. Don't confuse yourself by thinking too far ahead.", # pylint: disable=line-too-long + "buzz_words": "You used 14 buzz words. The topics of your answer are acceptable. Make sure to ", # pylint: disable=line-too-long + "grade_analysis": "Your grade is 20/20. This should be your go to answer, but it all depends on the interviewer. This answer should could out naturally and be your basis.", # pylint: disable=line-too-long + }, f"Expected a 20 grade report. Instead it returned {actual}" + def test_grade_transcription_gt5(self): """testing grade_transcription function in ML with a recording of many filler/buzz words""" - PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) + project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) tests_path = "tests" file_name = "gt5.aiff" - file_path = os.path.join(PROJECT_ROOT, tests_path, file_name) + file_path = os.path.join(project_root, tests_path, file_name) actual = ML.grade_transcription(ML.audio_to_text(file_path)) - assert isinstance(actual, dict), f"Expected grade_transcription to return a dict. Instead it returned a {actual}" - assert (actual == {"filler_words": "You did not use any filler words. Or there was a problem with the audio transcript. Either way, remember to talk confidently and at a good pace.", - "buzz_words": "You did not use any buzz words. When answering this question, try to talk about your education, work experiences, major, or any jobs you had.", - "grade_analysis": "Your grade is 0/20. You should rethink your answer to be more focused and clearly thought out."} - ), f"Expected a 0 grade report. Instead it returned {actual}" - + assert isinstance( + actual, dict + ), f"Expected grade_transcription to return a dict. Instead it returned a {actual}" + assert actual == { + "filler_words": "You did not use any filler words. Or there was a problem with the audio transcript. Either way, remember to talk confidently and at a good pace.", # pylint: disable=line-too-long + "buzz_words": "You did not use any buzz words. When answering this question, try to talk about your education, work experiences, major, or any jobs you had.", # pylint: disable=line-too-long + "grade_analysis": "Your grade is 0/20. You should rethink your answer to be more focused and clearly thought out.", # pylint: disable=line-too-long + }, f"Expected a 0 grade report. Instead it returned {actual}" + def test_grade_transcription_5(self): """testing grade_transcription function in ML with a recording of 5 filler/buzz""" - PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) + project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) tests_path = "tests" file_name = "5.aiff" - file_path = os.path.join(PROJECT_ROOT, tests_path, file_name) + file_path = os.path.join(project_root, tests_path, file_name) actual = ML.grade_transcription(ML.audio_to_text(file_path)) - assert isinstance(actual, dict), f"Expected grade_transcription to return a dict. Instead it returned a {actual}" - assert (actual == {"filler_words": "You used 16 filler words. When giving your answer, try speaking slower and more clearly. Don't confuse yourself by thinking too far ahead.", - "buzz_words": "You did not use any buzz words. When answering this question, try to talk about your education, work experiences, major, or any jobs you had.", - "grade_analysis": "Your grade is 0/20. You should rethink your answer to be more focused and clearly thought out."} - ), f"Expected a 0 grade report. Instead it returned {actual}" \ No newline at end of file + assert isinstance( + actual, dict + ), f"Expected grade_transcription to return a dict. Instead it returned a {actual}" + assert actual == { + "filler_words": "You used 16 filler words. When giving your answer, try speaking slower and more clearly. Don't confuse yourself by thinking too far ahead.", # pylint: disable=line-too-long + "buzz_words": "You did not use any buzz words. When answering this question, try to talk about your education, work experiences, major, or any jobs you had.", # pylint: disable=line-too-long + "grade_analysis": "Your grade is 0/20. You should rethink your answer to be more focused and clearly thought out.", # pylint: disable=line-too-long + }, f"Expected a 0 grade report. Instead it returned {actual}"