Anvit25 commited on
Commit
6f9996c
·
verified ·
1 Parent(s): 2bc6924

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -323
app.py CHANGED
@@ -1,326 +1,3 @@
1
- # import json
2
- # import os
3
- # from pathlib import Path
4
- # import numpy as np
5
- # from fastapi import FastAPI, Query
6
- # from fastapi.responses import FileResponse
7
-
8
- # # Use a dedicated library for creating text embeddings
9
- # from sentence_transformers import SentenceTransformer
10
-
11
- # # --- 1. Load the Local Embedding Model ---
12
- # # This line downloads (first time only) and loads a powerful, lightweight model
13
- # # into memory. This is much more efficient than using an API for this task.
14
- # print("Loading sentence-transformer model...")
15
- # embedding_model = SentenceTransformer('all-MiniLM-L6-v2')
16
- # print("Model loaded successfully.")
17
-
18
- # # --- 2. Load Image Metadata ---
19
- # try:
20
- # with open("image.json", "r") as f:
21
- # data = json.load(f)
22
- # except FileNotFoundError:
23
- # print("Error: image.json not found. Please make sure the file exists.")
24
- # exit()
25
-
26
- # image_list = []
27
- # image_dir = Path("images")
28
- # if not image_dir.exists():
29
- # print(f"Error: The '{image_dir}' directory does not exist.")
30
- # exit()
31
-
32
- # # Prepare list of images and descriptions
33
- # for page in data.get("pages", []):
34
- # for img in page.get("images", []):
35
- # description = img.get("description", "")
36
- # if not description:
37
- # continue
38
- # # Match description to a file in the images folder
39
- # for img_file in image_dir.iterdir():
40
- # if img_file.is_file() and description.lower() in img_file.name.lower():
41
- # image_list.append({"file": str(img_file), "description": description})
42
- # break # Move to the next description once a match is found
43
-
44
- # print(f"Found {len(image_list)} images with matching descriptions.")
45
-
46
-
47
- # # --- 3. Function to Get Embeddings Locally ---
48
- # def get_embedding(text: str) -> np.ndarray:
49
- # """
50
- # Generates an embedding for the given text using the local SentenceTransformer model.
51
- # """
52
- # # The model.encode() method directly returns a numpy array. It's fast and local.
53
- # return embedding_model.encode(text)
54
-
55
- # # --- 4. Precompute Embeddings for All Images ---
56
- # print("Precomputing embeddings for all image descriptions...")
57
- # for img in image_list:
58
- # # Each description is converted into a numerical vector (embedding)
59
- # img["embedding"] = get_embedding(img["description"])
60
- # print("Embeddings precomputed.")
61
-
62
-
63
- # # --- 5. FastAPI Application ---
64
- # app = FastAPI(title="Semantic Image Search API")
65
-
66
- # def cosine_similarity(vec1: np.ndarray, vec2: np.ndarray) -> float:
67
- # """Calculates the cosine similarity between two vectors."""
68
- # norm1 = np.linalg.norm(vec1)
69
- # norm2 = np.linalg.norm(vec2)
70
- # if norm1 == 0 or norm2 == 0:
71
- # return 0.0
72
- # return np.dot(vec1, vec2) / (norm1 * norm2)
73
-
74
- # @app.get("/search_image/")
75
- # async def search_image(query: str = Query(..., description="Search text")):
76
- # # Convert the user's search query into an embedding
77
- # query_emb = get_embedding(query)
78
-
79
- # best_match = None
80
- # highest_score = -1.0 # Cosine similarity ranges from -1 to 1
81
-
82
- # # Compare the query embedding to all precomputed image description embeddings
83
- # for img in image_list:
84
- # score = cosine_similarity(query_emb, img["embedding"])
85
- # if score > highest_score:
86
- # highest_score = score
87
- # best_match = img
88
-
89
- # if best_match:
90
- # print(f"Query: '{query}' -> Found best match: {best_match['file']} with score: {highest_score:.4f}")
91
- # return FileResponse(best_match["file"])
92
-
93
- # return {"error": "No matching image found"}
94
-
95
-
96
-
97
- # import json
98
- # import os
99
- # from pathlib import Path
100
- # import numpy as np
101
- # import requests
102
- # from typing import Optional, List, Tuple, Dict
103
-
104
- # import gradio as gr
105
- # from dotenv import load_dotenv
106
- # from gradio_client import Client, handle_file
107
- # from sentence_transformers import SentenceTransformer, util
108
-
109
- # # --- 1. SETUP AND MODEL LOADING ---
110
- # load_dotenv()
111
- # GROQ_API_KEY = os.getenv("GROQ_API_KEY") # Still used for summarizing results
112
-
113
- # if not GROQ_API_KEY:
114
- # raise ValueError("GROQ_API_KEY not found. It's needed for summarizing analysis results.")
115
-
116
- # print("Loading models and connecting to clients...")
117
- # # Model for local intent classification and image search
118
- # embedding_model = SentenceTransformer('all-MiniLM-L6-v2')
119
- # try:
120
- # chatbot_client = Client("Anvit25/LLM_chatbot2")
121
- # audio_client = Client("Anvit25/new_audio")
122
- # vision_client = Client("Anvit25/vision-classifier")
123
- # print("All models and clients loaded successfully.")
124
- # except Exception as e:
125
- # print(f"FATAL: Failed to connect to a Gradio client: {e}")
126
- # exit()
127
-
128
- # # --- 2. LOAD & PRECOMPUTE DATA FOR LOCAL SEARCH & INTENT ---
129
- # # Load local image data (same as before)
130
- # image_list = []
131
- # # ... (Your image loading and embedding logic is unchanged) ...
132
-
133
- # # NEW: Load intents from JSON and pre-compute their embeddings
134
- # intent_embeddings = {}
135
- # try:
136
- # with open("intents.json", "r") as f:
137
- # intents_data = json.load(f)
138
- # for intent, phrases in intents_data.items():
139
- # intent_embeddings[intent] = {
140
- # "phrases": phrases,
141
- # "embeddings": embedding_model.encode(phrases)
142
- # }
143
- # print("Local intent classifier loaded successfully.")
144
- # except FileNotFoundError:
145
- # print("FATAL: intents.json not found. This file is required for the local intent classifier.")
146
- # exit()
147
-
148
- # # --- 3. HELPER FUNCTIONS ---
149
-
150
- # def get_user_intent_local(user_query: str) -> dict:
151
- # """
152
- # Uses SentenceTransformer to classify user intent locally based on intents.json.
153
- # """
154
- # query_embedding = embedding_model.encode(user_query)
155
- # best_match = {"intent": "chat", "score": 0.7, "query": user_query} # Default to chat
156
-
157
- # for intent, data in intent_embeddings.items():
158
- # # Calculate cosine similarity between user query and all trigger phrases for an intent
159
- # scores = util.cos_sim(query_embedding, data["embeddings"])[0]
160
- # max_score = max(scores)
161
-
162
- # if max_score > best_match["score"]:
163
- # best_match["score"] = max_score.item()
164
- # best_match["intent"] = intent
165
- # # Extract the subject by removing the trigger phrase
166
- # best_phrase_index = np.argmax(scores)
167
- # trigger_phrase = data["phrases"][best_phrase_index]
168
- # subject = user_query.lower().replace(trigger_phrase.lower(), "").strip()
169
- # best_match["query"] = subject if subject else user_query
170
-
171
- # print(f"Local Intent Classifier Result: {best_match}")
172
- # return best_match
173
-
174
- # def summarize_analysis_with_groq(json_result: dict, context: str) -> str:
175
- # """
176
- # NEW: Takes a JSON/dict result and uses Groq to create a human-readable summary.
177
- # """
178
- # prompt = f"""
179
- # You are a helpful assistant. Based on the following technical analysis from a specialized AI model, provide a friendly and concise summary for the user.
180
- # Context: The user asked to '{context}'.
181
- # AI Model's Raw JSON Output:
182
- # ```json
183
- # {json.dumps(json_result, indent=2)}
184
- # ```
185
- # Your friendly, easy-to-understand summary:
186
- # """
187
- # try:
188
- # response = requests.post(
189
- # "https://api.groq.com/openai/v1/chat/completions",
190
- # headers={"Authorization": f"Bearer {GROQ_API_KEY}"},
191
- # json={"messages": [{"role": "user", "content": prompt}], "model": "llama3-8b-8192"},
192
- # )
193
- # response.raise_for_status()
194
- # return response.json()["choices"][0]["message"]["content"]
195
- # except Exception as e:
196
- # print(f"Groq summary error: {e}")
197
- # return f"I finished the analysis, but had trouble summarizing it. Here is the raw data:\n`{json.dumps(json_result)}`"
198
-
199
-
200
- # # ... (cosine_similarity and find_best_matching_image functions are unchanged) ...
201
- # def find_best_matching_image(query: str) -> Optional[dict]: # ... (Identical) ...
202
- # pass
203
- # def generate_groq_narrative(user_query: str, search_result: Optional[dict]) -> str: # ... (Identical) ...
204
- # pass
205
-
206
- # # --- 4. CORE GRADIO LOGIC (UPDATED) ---
207
-
208
- # def handle_image_analysis(file_path: str) -> str:
209
- # """Analyzes an image and returns a text summary."""
210
- # try:
211
- # vision_result = vision_client.predict(image=handle_file(file_path), api_name="/predict")
212
- # # NEW: Summarize the JSON result
213
- # summary = summarize_analysis_with_groq(vision_result, "Analyze this image")
214
- # return summary
215
- # except Exception as e:
216
- # return f"Sorry, I couldn't analyze the image. Error: {e}"
217
-
218
- # def handle_audio_analysis(file_path: str) -> str:
219
- # """Analyzes audio and returns a text summary."""
220
- # try:
221
- # prediction_text, _ = audio_client.predict(audio_filepath=handle_file(file_path), api_name="/predict")
222
- # return f"The audio analysis result is: **{prediction_text}**"
223
- # except Exception as e:
224
- # return f"Sorry, I couldn't analyze the audio. Error: {e}"
225
-
226
-
227
- # def chat_interface(user_input: dict, history: List[Tuple[str, str]]):
228
- # """
229
- # The main function that powers the Gradio chat interface.
230
- # It now prioritizes file uploads over text for intent classification.
231
- # """
232
- # user_text = user_input["text"].strip()
233
- # user_files = user_input["files"]
234
- # new_history = history or []
235
-
236
- # bot_message = ""
237
-
238
- # # === Priority 1: Handle file uploads ===
239
- # if user_files:
240
- # file_path = user_files[0]
241
- # # Display the uploaded file in the chat
242
- # new_history.append(((file_path,), None))
243
-
244
- # if file_path.lower().endswith(('.png', '.jpg', '.jpeg', '.webp')):
245
- # bot_message = handle_image_analysis(file_path)
246
- # elif file_path.lower().endswith(('.wav', '.mp3', '.flac')):
247
- # bot_message = handle_audio_analysis(file_path)
248
- # else:
249
- # bot_message = "I'm not sure how to handle that file type."
250
-
251
- # new_history[-1] = (new_history[-1][0], bot_message)
252
- # return new_history, None
253
-
254
- # # === Priority 2: Handle text-only queries if no files are uploaded ===
255
- # if not user_text:
256
- # return new_history, None
257
-
258
- # new_history.append((user_text, None))
259
- # intent_data = get_user_intent_local(user_text) # Use local classifier
260
- # intent = intent_data.get("intent")
261
- # query_subject = intent_data.get("query")
262
-
263
- # if intent == "chat":
264
- # prediction = chatbot_client.predict(user_input=query_subject, api_name="/chatbot_response")
265
- # bot_message = prediction[-1]['content']
266
-
267
- # elif intent == "search_local_image":
268
- # found_image = find_best_matching_image(query_subject)
269
- # bot_message = generate_groq_narrative(query_subject, found_image)
270
- # new_history[-1] = (user_text, bot_message)
271
- # if found_image:
272
- # new_history.append((None, (found_image['file'],))) # Display image on new line
273
- # return new_history, None
274
-
275
- # # For these intents, we just prompt the user to upload a file
276
- # elif intent == "request_image_analysis":
277
- # bot_message = "Of course. Please upload the image you want me to analyze."
278
- # elif intent == "request_audio_analysis":
279
- # bot_message = "I'm ready. Please upload the audio file for analysis."
280
- # else:
281
- # bot_message = "I'm not sure how to handle that. Can you rephrase?"
282
-
283
- # new_history[-1] = (user_text, bot_message)
284
- # return new_history, None
285
-
286
-
287
- # # --- 5. GRADIO UI DEFINITION ---
288
- # with gr.Blocks(theme=gr.themes.Soft(), title="Multi-Modal AI Chatbot") as demo:
289
- # gr.Markdown("# Multi-Modal AI Chatbot")
290
- # gr.Markdown("I can chat, search for local images, or analyze images and audio you upload.")
291
-
292
- # # CORRECTED LINE: The 'bubble_fn' argument is removed.
293
- # chatbot_history = gr.Chatbot(height=600, show_copy_button=True, layout="bubble", render=False)
294
-
295
- # with gr.Row():
296
- # multimodal_textbox = gr.MultimodalTextbox(
297
- # file_types=["image", "audio"],
298
- # placeholder="Type your message or upload a file...",
299
- # submit_btn="Send",
300
- # render=False,
301
- # autofocus=True
302
- # )
303
-
304
- # # Render components after defining the layout
305
- # chatbot_history.render()
306
- # multimodal_textbox.render()
307
-
308
- # multimodal_textbox.submit(
309
- # fn=chat_interface,
310
- # inputs=[multimodal_textbox, chatbot_history],
311
- # outputs=[chatbot_history, multimodal_textbox]
312
- # )
313
-
314
- # if __name__ == "__main__":
315
- # demo.launch(debug=True)
316
-
317
-
318
-
319
-
320
-
321
-
322
-
323
-
324
  import json
325
  import os
326
  from pathlib import Path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import json
2
  import os
3
  from pathlib import Path