Mudassir939 commited on
Commit
eed10ed
·
verified ·
1 Parent(s): 55d69e8

Upload 7 files

Browse files
Files changed (7) hide show
  1. .dockerignore +5 -0
  2. .env +2 -0
  3. .gitignore +3 -0
  4. Dockerfile +21 -0
  5. README.md +8 -11
  6. app.py +118 -0
  7. requirements.txt +6 -0
.dockerignore ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ __pycache__
2
+ *.pyc
3
+ .git
4
+ .venv
5
+ uploads/
.env ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ GOOGLE_API_KEY=AIzaSyAHpElgh7EQ8SvLf7Sa2HwK-TtjOd6ZcqU
2
+ ASSEMBLYAI_API_KEY=ya54c7e8b00f746a4bdb501a312a197e7
.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # Ignore the virtual environment directory
2
+ venv/
3
+ .env
Dockerfile ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use an official Python runtime as a parent image
2
+ FROM python:3.9-slim
3
+
4
+ # Set the working directory in the container
5
+ WORKDIR /app
6
+
7
+ # Copy the current directory contents into the container at /app
8
+ COPY . /app
9
+
10
+ # Install any needed packages specified in requirements.txt
11
+ RUN pip install --no-cache-dir -r requirements.txt
12
+
13
+ # Make port 7860 available to the world outside this container
14
+ EXPOSE 7860
15
+
16
+ # Define environment variables if needed
17
+ ENV GOOGLE_API_KEY = "AIzaSyAHpElgh7EQ8SvLf7Sa2HwK-TtjOd6ZcqU"
18
+ ENV ASSEMBLYAI_API_KEY = "ya54c7e8b00f746a4bdb501a312a197e7"
19
+
20
+ # Run app.py when the container launches using Gunicorn
21
+ CMD ["gunicorn", "-b", "0.0.0.0:7860", "app:app"]
README.md CHANGED
@@ -1,11 +1,8 @@
1
- ---
2
- title: Basic Docker SDK Space
3
- emoji: 🐳
4
- colorFrom: purple
5
- colorTo: gray
6
- sdk: docker
7
- app_port: 7860
8
- ---
9
-
10
-
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
+ ---
2
+ title: Basic Docker SDK Space
3
+ emoji: 🐳
4
+ colorFrom: purple
5
+ colorTo: gray
6
+ sdk: docker
7
+ app_port: 7860
8
+ ---
 
 
 
app.py ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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('application/javascript', '.js')
12
+ mimetypes.add_type('text/css', '.css')
13
+
14
+ load_dotenv()
15
+
16
+ # Initialize the Flask app
17
+ app = Flask(__name__)
18
+
19
+ # Get API keys from environment variables
20
+ ASSEMBLYAI_API_KEY = os.getenv("ASSEMBLYAI_API_KEY")
21
+ GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
22
+
23
+ # Set AssemblyAI API key
24
+ aai.settings.api_key = ASSEMBLYAI_API_KEY
25
+
26
+ # Set Google API key for Gemini model
27
+ os.environ["GOOGLE_API_KEY"] = GOOGLE_API_KEY
28
+
29
+ # Define a directory to save uploaded audio files
30
+ UPLOAD_FOLDER = 'uploads'
31
+ os.makedirs(UPLOAD_FOLDER, exist_ok=True)
32
+ app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
33
+
34
+ # Refined Instructions for Gemini
35
+ GEMINI_INSTRUCTIONS = """
36
+ The purpose of the category 'Reason for Outbound Call' is to identify the reason that a connected call was placed by the caller.
37
+
38
+ Consider the following options and select the one that best matches the content of the call:
39
+ 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.
40
+ 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.
41
+ 3. No: The agent only confirmed, changed, or canceled an existing appointment. This includes any mention of scheduling, rescheduling, confirming, or canceling appointments.
42
+ 4. Correction: The call was not connected to the intended party (e.g., it was a voicemail or a one-sided message).
43
+
44
+ Remember:
45
+ - Option 1 should only be selected if there was a live conversation with the intended contact.
46
+ - Option 4 should be selected if the call was not connected (e.g., it was a voicemail or no live interaction occurred).
47
+ - Option 4 it is voice mail, make it option 4
48
+ """
49
+
50
+ # Home route to serve the index.html file
51
+ @app.route('/')
52
+ def home():
53
+ return send_file('web/index.html')
54
+
55
+ # API route to handle file upload, transcription, and model interaction
56
+ @app.route("/api/upload", methods=["POST"])
57
+ def generate_api():
58
+ if request.method == "POST":
59
+ try:
60
+ # Check if an audio file was uploaded
61
+ if 'audio_file' not in request.files:
62
+ return jsonify({"error": "No audio file provided"}), 400
63
+
64
+ audio_file = request.files['audio_file']
65
+ if audio_file.filename == '':
66
+ return jsonify({"error": "No selected file"}), 400
67
+
68
+ # Save the uploaded file to the server
69
+ file_path = os.path.join(app.config['UPLOAD_FOLDER'], audio_file.filename)
70
+ audio_file.save(file_path)
71
+
72
+ # Transcribe the audio using AssemblyAI
73
+ transcriber = aai.Transcriber()
74
+ transcript = transcriber.transcribe(file_path)
75
+
76
+ # Send transcription and instructions to Gemini model
77
+ model = ChatGoogleGenerativeAI(model="gemini-pro")
78
+ message = HumanMessage(content=f"{GEMINI_INSTRUCTIONS}\n\nCall Transcription: {transcript.text}")
79
+ response = model.stream([message])
80
+
81
+ # Interpret the model's response to select the correct option
82
+ buffer = []
83
+ for chunk in response:
84
+ buffer.append(chunk.content)
85
+
86
+ result_text = ''.join(buffer).lower()
87
+
88
+ # Adjusted logic to determine the correct option
89
+ if ("option 4" in result_text or "voicemail" in result_text or
90
+ "just wanted to reach out" in result_text or "thank you, bye" in result_text or
91
+ "this is" in result_text and "see if" in result_text and not "response" in result_text):
92
+ selected_option = 4
93
+ elif "option 1" in result_text or "yes" in result_text or "vehicle needs" in result_text:
94
+ selected_option = 1
95
+ elif "option 2" in result_text:
96
+ selected_option = 2
97
+ elif "option 3" in result_text or "reschedule" in result_text or "confirm" in result_text or "cancel" in result_text:
98
+ selected_option = 3
99
+ else:
100
+ selected_option = "Could not determine the correct option."
101
+
102
+ # Return the transcription and selected option
103
+ return jsonify({
104
+ "transcription": transcript.text,
105
+ "selected_option": selected_option
106
+ }), 200
107
+
108
+ except Exception as e:
109
+ return jsonify({"error": str(e)})
110
+
111
+ # Route to serve static files
112
+ @app.route('/<path:path>')
113
+ def serve_static(path):
114
+ return send_from_directory('web', path)
115
+
116
+ # Run the Flask application
117
+ if __name__ == '__main__':
118
+ app.run(debug=True)
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ Flask
2
+ gunicorn
3
+ langchain-google-genai
4
+ langchain-core
5
+ assemblyai
6
+ python-dotenv