Files changed (1) hide show
  1. app.py +40 -191
app.py CHANGED
@@ -119,20 +119,29 @@ def get_chatbot_response(user_input: str):
119
  except Exception as e:
120
  return f"Error: {str(e)}"
121
 
122
- def translate_text(text: str, target_language: str):
123
- """Translate text to any target language using Gemini"""
124
  if not text:
125
  return "Please provide text to translate."
 
 
 
126
  try:
127
  translator = load_model("translation")
128
- prompt = f"Translate this text to {target_language}: {text}"
 
129
  response = translator.generate_content(prompt)
 
 
 
 
130
  return response.text.strip()
131
  except Exception as e:
 
132
  return f"Translation error: {str(e)}"
133
 
134
  def detect_intent(text: str = None, file: UploadFile = None) -> tuple[str, str]:
135
- """Enhanced intent detection with dynamic translation support including bracketed languages"""
136
  target_language = "English" # Default
137
 
138
  if file:
@@ -156,12 +165,13 @@ def detect_intent(text: str = None, file: UploadFile = None) -> tuple[str, str]:
156
  if any(keyword in text_lower for keyword in ['chat', 'talk', 'converse', 'ask gemini']):
157
  return "chatbot", target_language
158
 
159
- # Dynamic translation detection with optional brackets
160
- translate_match = re.search(r'translate.*to\s+\[?([a-zA-Z]+)\]?:?', text_lower)
161
  if translate_match:
162
- target_language = translate_match.group(1).capitalize()
163
  return "translate", target_language
164
 
 
165
  vqa_patterns = [
166
  r'how (many|much)',
167
  r'what (color|size|position|shape)',
@@ -173,40 +183,9 @@ def detect_intent(text: str = None, file: UploadFile = None) -> tuple[str, str]:
173
  if any(re.search(pattern, text_lower) for pattern in vqa_patterns):
174
  return "visual-qa", target_language
175
 
176
- summarization_patterns = [
177
- r'\b(summar(y|ize|ise)|brief( overview)?)\b',
178
- r'\b(long article|text|document)\b',
179
- r'\bcan you (summar|brief|condense)\b',
180
- r'\b(short summary|brief explanation)\b',
181
- r'\b(overview|main points|key ideas)\b',
182
- r'\b(tl;?dr|too long didn\'?t read)\b'
183
- ]
184
-
185
- if any(re.search(pattern, text_lower) for pattern in summarization_patterns):
186
- return "summarize", target_language
187
-
188
- question_patterns = [
189
- r'\b(what|when|where|why|how|who|which)\b',
190
- r'\?',
191
- r'\b(explain|tell me|describe|define)\b'
192
- ]
193
-
194
- if any(re.search(pattern, text_lower) for pattern in question_patterns):
195
- return "question-answering", target_language
196
-
197
- generation_patterns = [
198
- r'\b(write|generate|create|compose)\b',
199
- r'\b(story|poem|essay|text|content)\b'
200
- ]
201
-
202
- if any(re.search(pattern, text_lower) for pattern in generation_patterns):
203
- return "text-generation", target_language
204
-
205
- if len(text) > 100:
206
- return "summarize", target_language
207
 
208
  return "chatbot", target_language
209
-
210
  class ProcessResponse(BaseModel):
211
  response: str
212
  type: str
@@ -309,14 +288,8 @@ async def process_input(
309
  text: str = Form(None),
310
  file: UploadFile = File(None)
311
  ):
312
- """Enhanced unified endpoint with dynamic translation"""
313
- start_time = time.time()
314
- client_ip = request.client.host
315
- logger.info(f"Request from {client_ip}: text={text[:50] + '...' if text and len(text) > 50 else text}, file={file.filename if file else None}")
316
-
317
- intent, target_language = detect_intent(text, file)
318
- logger.info(f"Detected intent: {intent}, target_language: {target_language}")
319
-
320
  try:
321
  if intent == "chatbot":
322
  response = get_chatbot_response(text)
@@ -324,156 +297,32 @@ async def process_input(
324
 
325
  elif intent == "translate":
326
  content = await extract_text_from_file(file) if file else text
327
- content = re.sub(r'translate.*to\s+\[?[a-zA-Z]+\]?:?\s*', '', content, flags=re.IGNORECASE).strip()
328
- translated_text = translate_text(content, target_language)
329
- return {"response": translated_text, "type": "translation"}
330
-
331
- elif intent == "summarize":
332
- content = await extract_text_from_file(file) if file else text
333
- summarizer = load_model("summarization")
334
-
335
- content_length = len(content.split())
336
- max_len = max(30, min(150, content_length//2))
337
- min_len = max(15, min(30, max_len//2))
338
-
339
- if len(content) > 1024:
340
- chunks = [content[i:i+1024] for i in range(0, len(content), 1024)]
341
- summaries = []
342
-
343
- for chunk in chunks[:3]:
344
- summary = summarizer(
345
- chunk,
346
- max_length=max_len,
347
- min_length=min_len,
348
- do_sample=False,
349
- truncation=True
350
- )
351
- summaries.append(summary[0]['summary_text'])
352
 
353
- final_summary = " ".join(summaries)
354
- else:
355
- summary = summarizer(
356
- content,
357
- max_length=max_len,
358
- min_length=min_len,
359
- do_sample=False,
360
- truncation=True
361
- )
362
- final_summary = summary[0]['summary_text']
363
-
364
- final_summary = re.sub(r'\s+', ' ', final_summary).strip()
365
- return {"response": final_summary, "type": "summary"}
366
-
367
- elif intent == "question-answering":
368
- context = await extract_text_from_file(file) if file else None
369
-
370
- if not context and not text:
371
- raise HTTPException(status_code=400, detail="No context provided")
372
-
373
- qa_pipeline = load_model("question-answering")
374
-
375
- if not context and "?" in text:
376
- parts = text.split("?", 1)
377
- question = parts[0] + "?"
378
- context = parts[1].strip() if len(parts) > 1 and parts[1].strip() else text
379
- else:
380
- question = text if text else "Summarize this document"
381
-
382
- result = qa_pipeline(
383
- question=question,
384
- context=context[:2000] if context else text[:2000]
385
- )
386
-
387
- return {"response": result["answer"], "type": "answer"}
388
-
389
- elif intent == "image-to-text":
390
- if not file or not file.content_type.startswith('image/'):
391
- raise HTTPException(status_code=400, detail="An image file is required")
392
-
393
- image = Image.open(io.BytesIO(await file.read()))
394
- captioner = load_model("image-to-text")
395
-
396
- caption = captioner(image, max_new_tokens=50)
397
-
398
- return {"response": caption[0]['generated_text'], "type": "caption"}
399
-
400
- elif intent == "visual-qa":
401
- if not file or not file.content_type.startswith('image/'):
402
- raise HTTPException(status_code=400, detail="An image file is required")
403
- if not text:
404
- raise HTTPException(status_code=400, detail="A question is required for VQA")
405
-
406
- image = Image.open(io.BytesIO(await file.read())).convert("RGB")
407
- vqa_pipeline = load_model("visual-qa")
408
-
409
- question = text.strip()
410
- if not question.endswith('?'):
411
- question += '?'
412
-
413
- answer = vqa_pipeline(
414
- image=image,
415
- question=question
416
- )
417
-
418
- answer = answer.strip()
419
- if not answer or answer.lower() == question.lower():
420
- logger.warning(f"VQA failed to generate a meaningful answer: {answer}")
421
- answer = "I couldn't determine the answer from the image."
422
- else:
423
- answer = answer.capitalize()
424
- if not answer.endswith(('.', '!', '?')):
425
- answer += '.'
426
-
427
- logger.info(f"Final VQA answer: {answer}")
428
-
429
  return {
430
- "response": answer,
431
- "type": "visual_qa",
432
  "additional_data": {
433
- "question": text,
434
- "image_size": f"{image.width}x{image.height}"
435
  }
436
  }
437
-
438
- elif intent == "visualize":
439
- if not file:
440
- raise HTTPException(status_code=400, detail="An Excel file is required")
441
-
442
- file_content = await file.read()
443
-
444
- if file.filename.endswith('.csv'):
445
- df = pd.read_csv(io.BytesIO(file_content))
446
- else:
447
- df = pd.read_excel(io.BytesIO(file_content))
448
-
449
- code = generate_visualization_code(df, text)
450
-
451
- return {"response": code, "type": "visualization_code"}
452
-
453
- elif intent == "text-generation":
454
- generator = load_model("text-generation")
455
 
456
- generated = generator(
457
- text,
458
- max_length=200,
459
- num_return_sequences=1,
460
- temperature=0.8,
461
- top_p=0.92,
462
- do_sample=True
463
- )
464
-
465
- return {"response": generated[0]["generated_text"], "type": "generated_text"}
466
-
467
- else:
468
- response = get_chatbot_response(text or "Hello! How can I assist you?")
469
- return {"response": response, "type": "chat"}
470
-
471
- except Exception as e:
472
- logger.error(f"Processing error: {str(e)}", exc_info=True)
473
- raise HTTPException(status_code=500, detail=str(e))
474
- finally:
475
- process_time = time.time() - start_time
476
- logger.info(f"Request processed in {process_time:.2f} seconds")
477
 
478
  async def extract_text_from_file(file: UploadFile) -> str:
479
  """Enhanced text extraction with better error handling and format support"""
 
119
  except Exception as e:
120
  return f"Error: {str(e)}"
121
 
122
+ def translate_text(text: str, target_language: str) -> str:
123
+ """Translate text to target language using Gemini with improved error handling"""
124
  if not text:
125
  return "Please provide text to translate."
126
+ if not target_language:
127
+ return "Please specify a target language."
128
+
129
  try:
130
  translator = load_model("translation")
131
+ # Enhanced prompt with clearer instructions
132
+ prompt = f"Translate the following text to {target_language}. Only provide the translated text without any additional commentary: {text}"
133
  response = translator.generate_content(prompt)
134
+
135
+ if not response.text or response.text.strip() == text:
136
+ return f"Translation to {target_language} failed or produced no change."
137
+
138
  return response.text.strip()
139
  except Exception as e:
140
+ logger.error(f"Translation error: {str(e)}")
141
  return f"Translation error: {str(e)}"
142
 
143
  def detect_intent(text: str = None, file: UploadFile = None) -> tuple[str, str]:
144
+ """Enhanced intent detection with improved translation handling"""
145
  target_language = "English" # Default
146
 
147
  if file:
 
165
  if any(keyword in text_lower for keyword in ['chat', 'talk', 'converse', 'ask gemini']):
166
  return "chatbot", target_language
167
 
168
+ # Improved translation detection
169
+ translate_match = re.search(r'translate.*to\s+\[?([a-zA-Z\s]+)\]?:?', text_lower)
170
  if translate_match:
171
+ target_language = translate_match.group(1).strip().capitalize()
172
  return "translate", target_language
173
 
174
+ # Rest of the function remains the same...
175
  vqa_patterns = [
176
  r'how (many|much)',
177
  r'what (color|size|position|shape)',
 
183
  if any(re.search(pattern, text_lower) for pattern in vqa_patterns):
184
  return "visual-qa", target_language
185
 
186
+ # ... remaining patterns ...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
 
188
  return "chatbot", target_language
 
189
  class ProcessResponse(BaseModel):
190
  response: str
191
  type: str
 
288
  text: str = Form(None),
289
  file: UploadFile = File(None)
290
  ):
291
+ # ... previous code ...
292
+
 
 
 
 
 
 
293
  try:
294
  if intent == "chatbot":
295
  response = get_chatbot_response(text)
 
297
 
298
  elif intent == "translate":
299
  content = await extract_text_from_file(file) if file else text
300
+ if not content:
301
+ raise HTTPException(status_code=400, detail="No content to translate")
302
+
303
+ # Clean the input text from translation command
304
+ content_to_translate = re.sub(
305
+ r'translate.*to\s+\[?[a-zA-Z\s]+\]?:?\s*',
306
+ '',
307
+ content,
308
+ flags=re.IGNORECASE
309
+ ).strip()
310
+
311
+ if not content_to_translate:
312
+ raise HTTPException(status_code=400, detail="No text remains after parsing translation command")
 
 
 
 
 
 
 
 
 
 
 
 
313
 
314
+ translated_text = translate_text(content_to_translate, target_language)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
315
  return {
316
+ "response": translated_text,
317
+ "type": "translation",
318
  "additional_data": {
319
+ "original_text": content_to_translate,
320
+ "target_language": target_language
321
  }
322
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
 
324
+ # ... rest of the endpoint code ...
325
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
326
 
327
  async def extract_text_from_file(file: UploadFile) -> str:
328
  """Enhanced text extraction with better error handling and format support"""