bkbilal09 commited on
Commit
2bdd6a2
Β·
verified Β·
1 Parent(s): 305baea

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -59
app.py CHANGED
@@ -5,102 +5,126 @@ from langchain_community.vectorstores import FAISS
5
  from langchain_huggingface import HuggingFaceEmbeddings
6
  from langchain_text_splitters import RecursiveCharacterTextSplitter
7
  from langchain_groq import ChatGroq
8
- from langchain.chains import RetrievalQA
9
- from langchain.prompts import PromptTemplate
 
10
 
11
- # --- 1. CONFIGURATION & SECRETS ---
12
- # Note: On Hugging Face, add GROQ_API_KEY in Settings > Secrets
13
  GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
14
 
15
- # Initialize LLM (Llama 3 via Groq is ultra-fast)
16
  llm = ChatGroq(
17
  temperature=0.1,
18
  model_name="llama-3.3-70b-versatile",
19
- groq_api_key=GROQ_API_KEY
20
  )
21
 
22
- # Initialize Embeddings (Lightweight & effective for medical text)
23
  embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
24
 
25
- # --- 2. CORE LOGIC ---
26
 
27
- def process_and_query(pdf_file, user_question):
28
  if not pdf_file:
29
- return "Please upload a medical report first."
30
 
31
  try:
32
- # Step A: Extract Text
33
  doc = fitz.open(pdf_file.name)
34
  text = ""
35
  for page in doc:
36
  text += page.get_text()
37
 
38
- # Step B: Chunking (Medical context needs smaller chunks for precision)
 
 
 
39
  text_splitter = RecursiveCharacterTextSplitter(
40
- chunk_size=600,
41
- chunk_overlap=100,
42
- separators=["\n\n", "\n", ".", " "]
43
  )
44
  chunks = text_splitter.split_text(text)
45
 
46
- # Step C: Vector Database (FAISS)
47
  vector_db = FAISS.from_texts(chunks, embeddings)
48
-
49
- # Step D: Triage & Custom Prompting
50
- # This prompt forces the AI to check for urgency and standardize units
51
- template = """
52
- You are a specialized Medical Cross-Border Assistant.
53
- Context from the patient's report: {context}
54
-
55
- Guidelines:
56
- 1. If the user asks for a summary, include: Urgency Level (Low/High),
57
- Key Findings, and standardized units (e.g., convert units if needed).
58
- 2. Use simple, empathetic language for a migrant/traveler.
59
- 3. If you see critical values, flag them for immediate doctor consultation.
60
-
61
- Question: {question}
62
- Answer:"""
63
-
64
- PROMPT = PromptTemplate(template=template, input_variables=["context", "question"])
65
-
66
- # Step E: RAG Chain
67
- chain = RetrievalQA.from_chain_type(
68
- llm=llm,
69
- chain_type="stuff",
70
- retriever=vector_db.as_retriever(search_kwargs={"k": 3}),
71
- chain_type_kwargs={"prompt": PROMPT}
 
 
 
 
 
 
 
72
  )
73
-
74
- response = chain.invoke(user_question)
75
- return response["result"]
76
 
77
  except Exception as e:
78
- return f"Error processing file: {str(e)}"
79
 
80
- # --- 3. GRADIO UI DESIGN (Cyber-Luxe Style) ---
81
 
82
- with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="rose")) as demo:
83
- gr.Markdown("# πŸ₯ AI Cross-Border Health Navigator")
84
- gr.Markdown("### Standardize, Translate, and Understand your Medical Reports Instantly.")
 
 
 
 
 
 
 
 
 
 
85
 
86
  with gr.Row():
87
  with gr.Column(scale=1):
88
- file_input = gr.File(label="Upload Medical Report (PDF)", file_types=[".pdf"])
89
- question_input = gr.Textbox(
90
- label="Ask about the report",
91
- placeholder="e.g., 'Summarize this in Urdu' or 'Is my Glucose level high?'"
 
92
  )
93
- submit_btn = gr.Button("Analyze Report", variant="primary")
94
 
95
  with gr.Column(scale=2):
96
- output_text = gr.Textbox(label="AI Analysis & Insights", interactive=False, lines=15)
97
-
98
- gr.Examples(
99
- examples=[["sample_report.pdf", "Summarize this report and check for medical urgency."]],
100
- inputs=[file_input, question_input]
 
 
101
  )
102
 
103
- submit_btn.click(fn=process_and_query, inputs=[file_input, question_input], outputs=output_text)
 
104
 
105
  if __name__ == "__main__":
106
  demo.launch()
 
5
  from langchain_huggingface import HuggingFaceEmbeddings
6
  from langchain_text_splitters import RecursiveCharacterTextSplitter
7
  from langchain_groq import ChatGroq
8
+ from langchain_core.prompts import ChatPromptTemplate
9
+ from langchain_core.runnables import RunnablePassthrough
10
+ from langchain_core.output_parsers import StrOutputParser
11
 
12
+ # --- 1. SETUP & SECRETS ---
13
+ # Ensure "GROQ_API_KEY" is added to Hugging Face Secrets
14
  GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
15
 
16
+ # Use Llama 3 for medical reasoning
17
  llm = ChatGroq(
18
  temperature=0.1,
19
  model_name="llama-3.3-70b-versatile",
20
+ api_key=GROQ_API_KEY
21
  )
22
 
23
+ # Best open-source embeddings for medical text
24
  embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
25
 
26
+ # --- 2. THE RAG LOGIC ---
27
 
28
+ def process_medical_report(pdf_file, user_question):
29
  if not pdf_file:
30
+ return "⚠️ Error: Please upload a medical PDF report first."
31
 
32
  try:
33
+ # Step A: PDF Text Extraction
34
  doc = fitz.open(pdf_file.name)
35
  text = ""
36
  for page in doc:
37
  text += page.get_text()
38
 
39
+ if not text.strip():
40
+ return "⚠️ Error: The PDF seems empty or is an image. Please provide a text-based PDF."
41
+
42
+ # Step B: Recursive Chunking
43
  text_splitter = RecursiveCharacterTextSplitter(
44
+ chunk_size=700,
45
+ chunk_overlap=150
 
46
  )
47
  chunks = text_splitter.split_text(text)
48
 
49
+ # Step C: Temporary Vector Store
50
  vector_db = FAISS.from_texts(chunks, embeddings)
51
+ retriever = vector_db.as_retriever(search_kwargs={"k": 3})
52
+
53
+ # Step D: Prompt Engineering (Medical Cross-Border Specialist)
54
+ medical_template = """
55
+ You are a Medical Cross-Border AI Agent. Your goal is to help patients understand reports
56
+ from different countries.
57
+
58
+ CONTEXT FROM REPORT:
59
+ {context}
60
+
61
+ INSTRUCTIONS:
62
+ 1. Summarize findings in simple terms.
63
+ 2. Detect URGENCY: Label as LOW, MEDIUM, or HIGH.
64
+ 3. Convert Units: If you see international units, explain them clearly.
65
+ 4. If a language other than English is requested, provide a high-quality translation.
66
+ 5. CRITICAL: If values are dangerous, tell the user to seek immediate care.
67
+
68
+ USER QUESTION: {question}
69
+ """
70
+
71
+ prompt = ChatPromptTemplate.from_template(medical_template)
72
+
73
+ # Step E: Modern LCEL Chain (Replaces RetrievalQA)
74
+ def format_docs(docs):
75
+ return "\n\n".join(doc.page_content for doc in docs)
76
+
77
+ rag_chain = (
78
+ {"context": retriever | format_docs, "question": RunnablePassthrough()}
79
+ | prompt
80
+ | llm
81
+ | StrOutputParser()
82
  )
83
+
84
+ # Execute
85
+ return rag_chain.invoke(user_question)
86
 
87
  except Exception as e:
88
+ return f"🚨 System Error: {str(e)}"
89
 
90
+ # --- 3. UI DESIGN (Gradio) ---
91
 
92
+ # Cyber-Luxe Theme setup
93
+ theme = gr.themes.Soft(
94
+ primary_hue="cyan",
95
+ secondary_hue="blue",
96
+ neutral_hue="slate",
97
+ ).set(
98
+ button_primary_background_fill="*primary_500",
99
+ button_primary_text_color="white",
100
+ )
101
+
102
+ with gr.Blocks(theme=theme) as demo:
103
+ gr.HTML("<h1 style='text-align: center;'>πŸ₯ AI Cross-Border Health Navigator</h1>")
104
+ gr.Markdown("---")
105
 
106
  with gr.Row():
107
  with gr.Column(scale=1):
108
+ file_upload = gr.File(label="1. Upload Medical PDF", file_types=[".pdf"])
109
+ chat_query = gr.Textbox(
110
+ label="2. Ask AI Agent",
111
+ placeholder="e.g. 'Summarize and check for urgency' or 'Translate to Urdu'",
112
+ lines=2
113
  )
114
+ analyze_btn = gr.Button("πŸš€ Start Analysis", variant="primary")
115
 
116
  with gr.Column(scale=2):
117
+ output_display = gr.Markdown("### πŸ” AI Insights will appear here...")
118
+
119
+ # Action
120
+ analyze_btn.click(
121
+ fn=process_medical_report,
122
+ inputs=[file_upload, chat_query],
123
+ outputs=output_display
124
  )
125
 
126
+ gr.Markdown("---")
127
+ gr.HTML("<p style='text-align: center; color: gray;'>Note: This is an AI prototype for hackathons. Not a substitute for professional medical advice.</p>")
128
 
129
  if __name__ == "__main__":
130
  demo.launch()