Spaces:
Sleeping
Sleeping
Mudassir939
commited on
Update app.py
Browse files
app.py
CHANGED
@@ -1,118 +1,117 @@
|
|
1 |
-
import os
|
2 |
-
import json
|
3 |
-
from flask import Flask, jsonify, request, send_file, send_from_directory
|
4 |
-
from langchain_core.messages import HumanMessage
|
5 |
-
from langchain_google_genai import ChatGoogleGenerativeAI
|
6 |
-
import assemblyai as aai
|
7 |
-
import mimetypes
|
8 |
-
from dotenv import load_dotenv
|
9 |
-
|
10 |
-
|
11 |
-
mimetypes.add_type('
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
UPLOAD_FOLDER =
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
- Option
|
46 |
-
- Option 4
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
audio_file
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
"
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
"
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
app.run(debug=True)
|
|
|
1 |
+
import os
|
2 |
+
import json
|
3 |
+
from flask import Flask, jsonify, request, send_file, send_from_directory
|
4 |
+
from langchain_core.messages import HumanMessage
|
5 |
+
from langchain_google_genai import ChatGoogleGenerativeAI
|
6 |
+
import assemblyai as aai
|
7 |
+
import mimetypes
|
8 |
+
from dotenv import load_dotenv
|
9 |
+
|
10 |
+
mimetypes.add_type('application/javascript', '.js')
|
11 |
+
mimetypes.add_type('text/css', '.css')
|
12 |
+
|
13 |
+
load_dotenv()
|
14 |
+
|
15 |
+
# Initialize the Flask app
|
16 |
+
app = Flask(__name__)
|
17 |
+
|
18 |
+
# Get API keys from environment variables
|
19 |
+
ASSEMBLYAI_API_KEY = os.getenv("ASSEMBLYAI_API_KEY")
|
20 |
+
GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
|
21 |
+
|
22 |
+
# Set AssemblyAI API key
|
23 |
+
aai.settings.api_key = ASSEMBLYAI_API_KEY
|
24 |
+
|
25 |
+
# Set Google API key for Gemini model
|
26 |
+
os.environ["GOOGLE_API_KEY"] = GOOGLE_API_KEY
|
27 |
+
|
28 |
+
# Define a directory to save uploaded audio files in a writable location
|
29 |
+
UPLOAD_FOLDER = '/tmp/uploads'
|
30 |
+
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
|
31 |
+
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
|
32 |
+
|
33 |
+
# Refined Instructions for Gemini
|
34 |
+
GEMINI_INSTRUCTIONS = """
|
35 |
+
The purpose of the category 'Reason for Outbound Call' is to identify the reason that a connected call was placed by the caller.
|
36 |
+
|
37 |
+
Consider the following options and select the one that best matches the content of the call:
|
38 |
+
1. Yes: The agent attempted to discuss buying, selling, trading, leasing, or test driving a vehicle. This includes any discussion of vehicle needs, interests, or potential sales, but this only applies if the call was live.
|
39 |
+
2. No: The agent followed up on a previous purchase or had a general discussion. This option should be selected if the call does not include any sales-related discussion.
|
40 |
+
3. No: The agent only confirmed, changed, or canceled an existing appointment. This includes any mention of scheduling, rescheduling, confirming, or canceling appointments.
|
41 |
+
4. Correction: The call was not connected to the intended party (e.g., it was a voicemail or a one-sided message).
|
42 |
+
|
43 |
+
Remember:
|
44 |
+
- Option 1 should only be selected if there was a live conversation with the intended contact.
|
45 |
+
- Option 4 should be selected if the call was not connected (e.g., it was a voicemail or no live interaction occurred).
|
46 |
+
- Option 4 it is voice mail, make it option 4
|
47 |
+
"""
|
48 |
+
|
49 |
+
# Home route to serve the index.html file
|
50 |
+
@app.route('/')
|
51 |
+
def home():
|
52 |
+
return send_file('web/index.html')
|
53 |
+
|
54 |
+
# API route to handle file upload, transcription, and model interaction
|
55 |
+
@app.route("/api/upload", methods=["POST"])
|
56 |
+
def generate_api():
|
57 |
+
if request.method == "POST":
|
58 |
+
try:
|
59 |
+
# Check if an audio file was uploaded
|
60 |
+
if 'audio_file' not in request.files:
|
61 |
+
return jsonify({"error": "No audio file provided"}), 400
|
62 |
+
|
63 |
+
audio_file = request.files['audio_file']
|
64 |
+
if audio_file.filename == '':
|
65 |
+
return jsonify({"error": "No selected file"}), 400
|
66 |
+
|
67 |
+
# Save the uploaded file to the server
|
68 |
+
file_path = os.path.join(app.config['UPLOAD_FOLDER'], audio_file.filename)
|
69 |
+
audio_file.save(file_path)
|
70 |
+
|
71 |
+
# Transcribe the audio using AssemblyAI
|
72 |
+
transcriber = aai.Transcriber()
|
73 |
+
transcript = transcriber.transcribe(file_path)
|
74 |
+
|
75 |
+
# Send transcription and instructions to Gemini model
|
76 |
+
model = ChatGoogleGenerativeAI(model="gemini-pro")
|
77 |
+
message = HumanMessage(content=f"{GEMINI_INSTRUCTIONS}\n\nCall Transcription: {transcript.text}")
|
78 |
+
response = model.stream([message])
|
79 |
+
|
80 |
+
# Interpret the model's response to select the correct option
|
81 |
+
buffer = []
|
82 |
+
for chunk in response:
|
83 |
+
buffer.append(chunk.content)
|
84 |
+
|
85 |
+
result_text = ''.join(buffer).lower()
|
86 |
+
|
87 |
+
# Adjusted logic to determine the correct option
|
88 |
+
if ("option 4" in result_text or "voicemail" in result_text or
|
89 |
+
"just wanted to reach out" in result_text or "thank you, bye" in result_text or
|
90 |
+
"this is" in result_text and "see if" in result_text and not "response" in result_text):
|
91 |
+
selected_option = 4
|
92 |
+
elif "option 1" in result_text or "yes" in result_text or "vehicle needs" in result_text:
|
93 |
+
selected_option = 1
|
94 |
+
elif "option 2" in result_text:
|
95 |
+
selected_option = 2
|
96 |
+
elif "option 3" in result_text or "reschedule" in result_text or "confirm" in result_text or "cancel" in result_text:
|
97 |
+
selected_option = 3
|
98 |
+
else:
|
99 |
+
selected_option = "Could not determine the correct option."
|
100 |
+
|
101 |
+
# Return the transcription and selected option
|
102 |
+
return jsonify({
|
103 |
+
"transcription": transcript.text,
|
104 |
+
"selected_option": selected_option
|
105 |
+
}), 200
|
106 |
+
|
107 |
+
except Exception as e:
|
108 |
+
return jsonify({"error": str(e)})
|
109 |
+
|
110 |
+
# Route to serve static files
|
111 |
+
@app.route('/<path:path>')
|
112 |
+
def serve_static(path):
|
113 |
+
return send_from_directory('web', path)
|
114 |
+
|
115 |
+
# Run the Flask application
|
116 |
+
if __name__ == '__main__':
|
117 |
+
app.run(debug=True)
|
|