WanIrfan commited on
Commit
82597a1
·
verified ·
1 Parent(s): e92b03a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +143 -2
app.py CHANGED
@@ -25,6 +25,13 @@ logger = logging.getLogger(__name__)
25
  # Load environment variables
26
  load_dotenv()
27
 
 
 
 
 
 
 
 
28
  # --- 1. NEW HELPER FUNCTIONS TO FIX 'TypeError' ---
29
  def hydrate_history(raw_history_list: list) -> list:
30
  """Converts a list of dicts from session back into LangChain Message objects."""
@@ -371,13 +378,46 @@ def reset_metrics(domain):
371
  return jsonify({"success": True, "message": f"Metrics reset for {domain}"})
372
  except Exception as e:
373
  return jsonify({"error": str(e)}), 500
374
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
  # --- 3. NEW API-ONLY ROUTES ---
376
 
377
  @app.route("/api/medical", methods=["POST"])
378
  def medical_api():
379
  try:
380
  data = request.json
 
 
 
 
381
  query = data.get("query")
382
  if not query:
383
  return jsonify({"error": "No query provided"}), 400
@@ -390,8 +430,43 @@ def medical_api():
390
  if not agent:
391
  return jsonify({"error": "Medical RAG system not loaded"}), 500
392
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
393
  # Run the agent
394
- response_dict = agent.answer(query, chat_history=history_for_agent)
 
 
 
 
395
 
396
  # Return the full, clean JSON response
397
  return jsonify(response_dict)
@@ -400,7 +475,73 @@ def medical_api():
400
  logger.error(f"Error on /api/medical: {e}", exc_info=True)
401
  return jsonify({"error": str(e)}), 500
402
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
403
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404
  if __name__ == "__main__":
405
  logger.info("Starting Flask app for deployment testing...")
406
  app.run(host="0.0.0.0", port=7860, debug=False)
 
25
  # Load environment variables
26
  load_dotenv()
27
 
28
+ # These are your "customers". You give them a key.
29
+ # In a real app, this would be in a database.
30
+ VALID_API_KEYS = {
31
+ "anak_mail_123": "Dr. Amelia Ritahani",
32
+ "irfan_test_key_456": "Irfan (self)",
33
+ "sistem_gelap": "Gelap"
34
+ }
35
  # --- 1. NEW HELPER FUNCTIONS TO FIX 'TypeError' ---
36
  def hydrate_history(raw_history_list: list) -> list:
37
  """Converts a list of dicts from session back into LangChain Message objects."""
 
378
  return jsonify({"success": True, "message": f"Metrics reset for {domain}"})
379
  except Exception as e:
380
  return jsonify({"error": str(e)}), 500
381
+
382
+ # Helper function to check API key
383
+ def check_api_key(request_data):
384
+ api_key = request_data.get("api_key")
385
+ if not api_key or api_key not in VALID_API_KEYS:
386
+ return False, {"error": "Invalid or missing API key"}, 401
387
+ logger.info(f"API request authenticated for user: {VALID_API_KEYS[api_key]}")
388
+ return True, None, None
389
+
390
+ # Helper function to save and process uploaded files (Base64)
391
+ def process_base64_file(base64_string, file_type):
392
+ try:
393
+ # Decode the base64 string
394
+ file_bytes = base64.b64decode(base64_string)
395
+
396
+ # Save to a temporary file
397
+ upload_dir = "Uploads"
398
+ os.makedirs(upload_dir, exist_ok=True)
399
+ # Use a unique filename
400
+ temp_filename = f"{file_type}_{int(time.time())}.tmp"
401
+ temp_path = os.path.join(upload_dir, temp_filename)
402
+
403
+ with open(temp_path, 'wb') as f:
404
+ f.write(file_bytes)
405
+
406
+ logger.info(f"Saved temporary {file_type} to {temp_path}")
407
+ return temp_path
408
+ except Exception as e:
409
+ logger.error(f"Error decoding/saving base64 file: {e}")
410
+ return None
411
  # --- 3. NEW API-ONLY ROUTES ---
412
 
413
  @app.route("/api/medical", methods=["POST"])
414
  def medical_api():
415
  try:
416
  data = request.json
417
+ is_valid, error_response, status_code = check_api_key(data)
418
+ if not is_valid:
419
+ return jsonify(error_response), status_code
420
+
421
  query = data.get("query")
422
  if not query:
423
  return jsonify({"error": "No query provided"}), 400
 
430
  if not agent:
431
  return jsonify({"error": "Medical RAG system not loaded"}), 500
432
 
433
+ # --- Handle File Uploads (Base64) ---
434
+ enhanced_query = query
435
+ temp_file_path = None
436
+
437
+ if data.get("document_base64"):
438
+ logger.info("API: Processing base64 document for Swarm")
439
+ doc_text = base64.b64decode(data.get("document_base64")).decode('utf-8')
440
+ swarm_answer = run_medical_swarm(doc_text, query)
441
+ response_dict = {
442
+ "answer": markdown_bold_to_html(swarm_answer),
443
+ "thoughts": "Swarm analysis complete.",
444
+ "validation": (True, "Swarm output generated."),
445
+ "source": "Medical Swarm",
446
+ "response_time": 0 # Not tracked for swarm in this path
447
+ }
448
+ return jsonify(response_dict)
449
+
450
+ elif data.get("image_base64"):
451
+ logger.info("API: Processing base64 image")
452
+ temp_file_path = process_base64_file(data.get("image_base64"), "image")
453
+ if not temp_file_path:
454
+ return jsonify({"error": "Invalid base64 image data"}), 400
455
+
456
+ with open(temp_file_path, "rb") as img_file:
457
+ img_data = base64.b64encode(img_file.read()).decode("utf-8")
458
+
459
+ vision_prompt = f"Analyze image. Query: '{query}'"
460
+ message = HumanMessage(content=[{"type": "text", "text": vision_prompt}, {"type": "image_url", "image_url": f"data:image/jpeg;base64,{img_data}"}])
461
+ visual_prediction = llm.invoke([message]).content
462
+ enhanced_query = (f'User Query: "{query}" Context from Image: "{visual_prediction}"')
463
+
464
  # Run the agent
465
+ response_dict = agent.answer(enhanced_query, chat_history=history_for_agent)
466
+
467
+ # Clean up temp file
468
+ if temp_file_path and os.path.exists(temp_file_path):
469
+ os.remove(temp_file_path)
470
 
471
  # Return the full, clean JSON response
472
  return jsonify(response_dict)
 
475
  logger.error(f"Error on /api/medical: {e}", exc_info=True)
476
  return jsonify({"error": str(e)}), 500
477
 
478
+ @app.route("/api/islamic", methods=["POST"])
479
+ def islamic_api():
480
+ try:
481
+ data = request.json
482
+ is_valid, error_response, status_code = check_api_key(data)
483
+ if not is_valid: return jsonify(error_response), status_code
484
+
485
+ query = data.get("query")
486
+ if not query: return jsonify({"error": "No query provided"}), 400
487
+
488
+ raw_history = data.get("history", [])
489
+ history_for_agent = hydrate_history(raw_history)
490
+
491
+ agent = rag_systems['islamic']
492
+ if not agent: return jsonify({"error": "Islamic RAG system not loaded"}), 500
493
+
494
+ enhanced_query = query
495
+ temp_file_path = None
496
+
497
+ if data.get("image_base64"):
498
+ logger.info("API: Processing base64 image")
499
+ temp_file_path = process_base64_file(data.get("image_base64"), "image")
500
+ if not temp_file_path:
501
+ return jsonify({"error": "Invalid base64 image data"}), 400
502
+
503
+ with open(temp_file_path, "rb") as img_file:
504
+ img_data = base64.b64encode(img_file.read()).decode("utf-8")
505
+
506
+ vision_prompt = f"Analyze image. Query: '{query}'"
507
+ message = HumanMessage(content=[{"type": "text", "text": vision_prompt}, {"type": "image_url", "image_url": f"data:image/jpeg;base64,{img_data}"}])
508
+ visual_prediction = llm.invoke([message]).content
509
+ enhanced_query = (f'User Query: "{query}" Context from Image: "{visual_prediction}"')
510
 
511
+ response_dict = agent.answer(enhanced_query, chat_history=history_for_agent)
512
+
513
+ if temp_file_path and os.path.exists(temp_file_path):
514
+ os.remove(temp_file_path)
515
+
516
+ return jsonify(response_dict)
517
+
518
+ except Exception as e:
519
+ logger.error(f"Error on /api/islamic: {e}", exc_info=True)
520
+ return jsonify({"error": str(e)}), 500
521
+
522
+ @app.route("/api/insurance", methods=["POST"])
523
+ def insurance_api():
524
+ try:
525
+ data = request.json
526
+ is_valid, error_response, status_code = check_api_key(data)
527
+ if not is_valid: return jsonify(error_response), status_code
528
+
529
+ query = data.get("query")
530
+ if not query: return jsonify({"error": "No query provided"}), 400
531
+
532
+ raw_history = data.get("history", [])
533
+ history_for_agent = hydrate_history(raw_history)
534
+
535
+ agent = rag_systems['insurance']
536
+ if not agent: return jsonify({"error": "Insurance RAG system not loaded"}), 500
537
+
538
+ response_dict = agent.answer(query, chat_history=history_for_agent)
539
+ return jsonify(response_dict)
540
+
541
+ except Exception as e:
542
+ logger.error(f"Error on /api/insurance: {e}", exc_info=True)
543
+ return jsonify({"error": str(e)}), 500
544
+
545
  if __name__ == "__main__":
546
  logger.info("Starting Flask app for deployment testing...")
547
  app.run(host="0.0.0.0", port=7860, debug=False)