adil9858 commited on
Commit
5c72936
Β·
verified Β·
1 Parent(s): 9028caa

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -63
app.py CHANGED
@@ -5,10 +5,11 @@ from pathlib import Path
5
  import tempfile
6
  import time
7
  from groq import Groq
 
8
 
9
  # --- Configuration ---
10
- # NOTE: In a real production app, use environment variables for keys!
11
  GROQ_CLIENT = Groq(api_key=os.environ.get('groq'))
 
12
 
13
  class MediClearBackend:
14
  """Handles the API logic to keep the UI code clean."""
@@ -20,11 +21,10 @@ class MediClearBackend:
20
 
21
  @staticmethod
22
  def analyze_medical_image(image_path):
23
- """Step 1: Extract technical info using Groq VLM"""
24
  try:
25
  base64_image = MediClearBackend.encode_image(image_path)
26
 
27
- # Create the message content with image
28
  messages = [
29
  {
30
  "role": "user",
@@ -35,18 +35,16 @@ class MediClearBackend:
35
  }
36
  ]
37
 
38
- # Use Groq API with streaming
39
  completion = GROQ_CLIENT.chat.completions.create(
40
  model="meta-llama/llama-4-scout-17b-16e-instruct",
41
  messages=messages,
42
- temperature=0.1, # Lower temperature for more consistent medical analysis
43
  max_completion_tokens=1024,
44
  top_p=0.9,
45
  stream=True,
46
  stop=None
47
  )
48
 
49
- # Collect the streamed response
50
  technical_data = ""
51
  for chunk in completion:
52
  if chunk.choices[0].delta.content:
@@ -58,51 +56,44 @@ class MediClearBackend:
58
 
59
  @staticmethod
60
  def summarize_for_patient(technical_text):
61
- """Step 2: Convert technical info to patient-friendly text using Groq"""
62
  try:
 
 
 
 
 
 
 
 
 
63
  system_prompt = """You are a senior medical doctor with 50 years of experience.
64
  Your role is to explain medical reports to patients in simple, reassuring, everyday language.
65
  Never mention the doctors name whatsoever.
66
-
67
- Structure your response as follows:
68
- 1. Start with a warm, reassuring greeting
69
- 2. Provide an overall assessment in simple terms
70
- 3. Explain key findings and what they mean compared to normal
71
- 4. Suggest next steps or recommendations
72
- 5. End with a reassuring closing statement
73
-
74
- Speak directly to the patient in a compassionate tone. Avoid medical jargon unless necessary, and when you use it, explain it clearly."""
75
 
76
- messages = [
77
- {
78
- "role": "system",
79
- "content": system_prompt
80
- },
81
- {
82
- "role": "user",
83
- "content": f"Please explain this medical analysis in simple, patient-friendly terms:\n\n{technical_text}"
84
- }
85
- ]
86
 
87
- completion = GROQ_CLIENT.chat.completions.create(
88
- model="meta-llama/llama-4-scout-17b-16e-instruct",
89
- messages=messages,
90
- temperature=0.3, # Slightly higher temperature for more natural patient communication
91
- max_completion_tokens=1024,
92
- top_p=0.9,
93
- stream=True,
94
- stop=None
95
- )
96
-
97
- # Collect the streamed response
98
- patient_summary = ""
99
- for chunk in completion:
100
- if chunk.choices[0].delta.content:
101
- patient_summary += chunk.choices[0].delta.content
102
-
103
- return patient_summary
104
  except Exception as e:
105
- raise Exception(f"Summary Error: {str(e)}")
106
 
107
  def process_single_image(image_file):
108
  """Process a single medical image and return the analysis"""
@@ -112,15 +103,10 @@ def process_single_image(image_file):
112
  return "❌ Please upload a medical image first."
113
 
114
  try:
115
- # Create progress updates
116
- progress_updates = []
117
-
118
- # Step 1: Technical analysis
119
- progress_updates.append("🩺 Step 1/2: Scanning image for medical details...")
120
  technical_data = backend.analyze_medical_image(image_file.name)
121
 
122
- # Step 2: Patient-friendly summary
123
- progress_updates.append("πŸ“ Step 2/2: Generating patient-friendly summary...")
124
  final_report = backend.summarize_for_patient(technical_data)
125
 
126
  # Format the final report
@@ -129,6 +115,8 @@ def process_single_image(image_file):
129
  {'='*60}
130
  🩺 MEDICAL ANALYSIS REPORT: {filename}
131
  {'='*60}
 
 
132
  {final_report}
133
  {'='*60}
134
  βœ… Analysis Complete - This tool provides AI-powered insights and is not a substitute for professional medical diagnosis.
@@ -146,14 +134,16 @@ def process_multiple_images(image_files):
146
  if not image_files:
147
  return "❌ Please upload at least one medical image."
148
 
149
- full_report = f"🩺 SEHATSCAN - COMPREHENSIVE MEDICAL ANALYSIS\n{'='*70}\n\n"
 
 
 
150
  total = len(image_files)
151
 
152
  for index, image_file in enumerate(image_files, 1):
153
  try:
154
  filename = Path(image_file.name).name
155
  full_report += f"\nπŸ“„ IMAGE {index}/{total}: {filename}\n{'-'*50}\n"
156
- full_report += "πŸ” Analyzing medical image...\n"
157
 
158
  # Process the image
159
  technical_data = backend.analyze_medical_image(image_file.name)
@@ -233,7 +223,7 @@ def create_gradio_interface():
233
  """
234
  # 🩺 SehatScan - Koshur AI
235
  ### Professional Medical Image Analysis
236
- **Powered by Groq & Llama 4 Scout**
237
  """
238
  )
239
 
@@ -276,13 +266,13 @@ def create_gradio_interface():
276
  # Clear button
277
  clear_btn = gr.Button("πŸ—‘οΈ Clear All", variant="stop")
278
 
279
- # Processing Info
280
  with gr.Group(elem_classes="processing"):
281
  gr.Markdown(
282
  """
283
- ⚑ **Fast Processing**
284
- Using Groq's accelerated inference for quick medical image analysis.
285
- Typical processing time: 10-30 seconds per image.
286
  """
287
  )
288
 
@@ -324,7 +314,7 @@ def create_gradio_interface():
324
  """
325
  )
326
 
327
- # Event handlers for single image analysis
328
  analyze_single_btn.click(
329
  fn=process_single_image,
330
  inputs=[single_image],
@@ -332,7 +322,6 @@ def create_gradio_interface():
332
  api_name="analyze_single"
333
  )
334
 
335
- # Event handlers for multiple image analysis
336
  analyze_batch_btn.click(
337
  fn=process_multiple_images,
338
  inputs=[multiple_images],
@@ -359,7 +348,7 @@ def create_gradio_interface():
359
  outputs=[output_text]
360
  )
361
 
362
- # Export functionality (simulated - in Gradio, users can copy from textbox)
363
  def export_report(text):
364
  if text:
365
  timestamp = time.strftime("%Y%m%d-%H%M%S")
@@ -373,12 +362,12 @@ def create_gradio_interface():
373
  outputs=[output_text]
374
  )
375
 
376
- # Examples section (commented out as we don't have example images)
377
  gr.Markdown("### 🎯 How to use:")
378
  gr.Markdown("""
379
  1. **Upload** a medical image (X-ray, MRI, CT scan, ultrasound, etc.)
380
  2. **Click Analyze** to get AI-powered medical insights
381
- 3. **Review** the patient-friendly explanation
382
  4. **Always consult** with healthcare professionals for medical decisions
383
  """)
384
 
 
5
  import tempfile
6
  import time
7
  from groq import Groq
8
+ import requests # We need to keep requests for Kimi K2
9
 
10
  # --- Configuration ---
 
11
  GROQ_CLIENT = Groq(api_key=os.environ.get('groq'))
12
+ HYPERBOLIC_KEY = os.environ.get('h_api_key') # For Kimi K2
13
 
14
  class MediClearBackend:
15
  """Handles the API logic to keep the UI code clean."""
 
21
 
22
  @staticmethod
23
  def analyze_medical_image(image_path):
24
+ """Step 1: Extract technical info using Groq VLM (Llama 4 Scout)"""
25
  try:
26
  base64_image = MediClearBackend.encode_image(image_path)
27
 
 
28
  messages = [
29
  {
30
  "role": "user",
 
35
  }
36
  ]
37
 
 
38
  completion = GROQ_CLIENT.chat.completions.create(
39
  model="meta-llama/llama-4-scout-17b-16e-instruct",
40
  messages=messages,
41
+ temperature=0.1,
42
  max_completion_tokens=1024,
43
  top_p=0.9,
44
  stream=True,
45
  stop=None
46
  )
47
 
 
48
  technical_data = ""
49
  for chunk in completion:
50
  if chunk.choices[0].delta.content:
 
56
 
57
  @staticmethod
58
  def summarize_for_patient(technical_text):
59
+ """Step 2: Convert technical info to patient-friendly text using Kimi K2 via Hyperbolic"""
60
  try:
61
+ if not HYPERBOLIC_KEY:
62
+ raise Exception("Hyperbolic API key not configured")
63
+
64
+ url = "https://api.hyperbolic.xyz/v1/chat/completions"
65
+ headers = {
66
+ "Content-Type": "application/json",
67
+ "Authorization": f"Bearer {HYPERBOLIC_KEY}"
68
+ }
69
+
70
  system_prompt = """You are a senior medical doctor with 50 years of experience.
71
  Your role is to explain medical reports to patients in simple, reassuring, everyday language.
72
  Never mention the doctors name whatsoever.
73
+ Structure:
74
+ 1. Warm greeting.
75
+ 2. Overall assessment.
76
+ 3. Key findings (compared to normal).
77
+ 4. Next steps.
78
+ 5. Reassuring closing.
79
+ Speak directly to the patient."""
 
 
80
 
81
+ data = {
82
+ "messages": [
83
+ {"role": "system", "content": system_prompt},
84
+ {"role": "user", "content": technical_text}
85
+ ],
86
+ "model": "moonshotai/Kimi-K2-Instruct", # This is the Kimi K2 model
87
+ "max_tokens": 4096,
88
+ "temperature": 0.1,
89
+ "top_p": 0.9
90
+ }
91
 
92
+ response = requests.post(url, headers=headers, json=data)
93
+ response.raise_for_status()
94
+ return response.json()['choices'][0]['message']['content']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  except Exception as e:
96
+ raise Exception(f"Summary Error (Kimi K2): {str(e)}")
97
 
98
  def process_single_image(image_file):
99
  """Process a single medical image and return the analysis"""
 
103
  return "❌ Please upload a medical image first."
104
 
105
  try:
106
+ # Step 1: Technical analysis with Groq (Llama 4 Scout)
 
 
 
 
107
  technical_data = backend.analyze_medical_image(image_file.name)
108
 
109
+ # Step 2: Patient-friendly summary with Kimi K2
 
110
  final_report = backend.summarize_for_patient(technical_data)
111
 
112
  # Format the final report
 
115
  {'='*60}
116
  🩺 MEDICAL ANALYSIS REPORT: {filename}
117
  {'='*60}
118
+ πŸ”¬ Technical Analysis (Llama 4 Scout): Medical image processed
119
+ πŸ“ Patient Summary (Kimi K2):
120
  {final_report}
121
  {'='*60}
122
  βœ… Analysis Complete - This tool provides AI-powered insights and is not a substitute for professional medical diagnosis.
 
134
  if not image_files:
135
  return "❌ Please upload at least one medical image."
136
 
137
+ full_report = f"🩺 SEHATSCAN - COMPREHENSIVE MEDICAL ANALYSIS\n"
138
+ full_report += f"πŸ”¬ Step 1: Groq (Llama 4 Scout) | πŸ“ Step 2: Hyperbolic (Kimi K2)\n"
139
+ full_report += f"{'='*70}\n\n"
140
+
141
  total = len(image_files)
142
 
143
  for index, image_file in enumerate(image_files, 1):
144
  try:
145
  filename = Path(image_file.name).name
146
  full_report += f"\nπŸ“„ IMAGE {index}/{total}: {filename}\n{'-'*50}\n"
 
147
 
148
  # Process the image
149
  technical_data = backend.analyze_medical_image(image_file.name)
 
223
  """
224
  # 🩺 SehatScan - Koshur AI
225
  ### Professional Medical Image Analysis
226
+ **πŸ”¬ Step 1: Groq (Llama 4 Scout) | πŸ“ Step 2: Hyperbolic (Kimi K2)**
227
  """
228
  )
229
 
 
266
  # Clear button
267
  clear_btn = gr.Button("πŸ—‘οΈ Clear All", variant="stop")
268
 
269
+ # Model Info
270
  with gr.Group(elem_classes="processing"):
271
  gr.Markdown(
272
  """
273
+ πŸ€– **AI Models Used:**
274
+ - **Step 1**: Groq + Llama 4 Scout (Medical Image Analysis)
275
+ - **Step 2**: Hyperbolic + Kimi K2 (Patient Communication)
276
  """
277
  )
278
 
 
314
  """
315
  )
316
 
317
+ # Event handlers
318
  analyze_single_btn.click(
319
  fn=process_single_image,
320
  inputs=[single_image],
 
322
  api_name="analyze_single"
323
  )
324
 
 
325
  analyze_batch_btn.click(
326
  fn=process_multiple_images,
327
  inputs=[multiple_images],
 
348
  outputs=[output_text]
349
  )
350
 
351
+ # Export functionality
352
  def export_report(text):
353
  if text:
354
  timestamp = time.strftime("%Y%m%d-%H%M%S")
 
362
  outputs=[output_text]
363
  )
364
 
365
+ # Instructions
366
  gr.Markdown("### 🎯 How to use:")
367
  gr.Markdown("""
368
  1. **Upload** a medical image (X-ray, MRI, CT scan, ultrasound, etc.)
369
  2. **Click Analyze** to get AI-powered medical insights
370
+ 3. **Review** the patient-friendly explanation (powered by Kimi K2)
371
  4. **Always consult** with healthcare professionals for medical decisions
372
  """)
373