Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,226 +1,299 @@
|
|
1 |
-
#!/usr/bin/env python3
|
2 |
-
"""
|
3 |
-
Gemini Vision Pro Medical Image Analysis - Secure Gradio Interface
|
4 |
-
API key is loaded only from environment variables or .env file (never exposed to users)
|
5 |
-
"""
|
6 |
-
|
7 |
import gradio as gr
|
8 |
import google.generativeai as genai
|
9 |
from PIL import Image
|
10 |
import json
|
11 |
-
import
|
12 |
import os
|
13 |
-
from
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
else:
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
base_prompt = (
|
46 |
-
"You are an expert medical AI assistant specializing in medical image analysis. "
|
47 |
-
"You have extensive training across radiology, pathology, dermatology, ophthalmology, and clinical medicine.\n"
|
48 |
-
"**ANALYSIS INSTRUCTIONS:**\n"
|
49 |
-
"- Use clear medical terminology with explanations for complex terms\n"
|
50 |
-
"- Structure your response with clear sections and headers\n"
|
51 |
-
"- Be thorough but concise\n"
|
52 |
-
"- Always mention limitations and emphasize the need for professional medical consultation\n"
|
53 |
-
"- Focus on observable findings rather than definitive diagnoses\n"
|
54 |
)
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
## 1. IMAGE ASSESSMENT
|
70 |
-
- Image type, quality, and technical adequacy
|
71 |
-
- Anatomical structures and regions visible
|
72 |
-
- Any artifacts or limitations
|
73 |
-
## 2. CLINICAL FINDINGS
|
74 |
-
- Normal anatomical structures observed
|
75 |
-
- Abnormal findings or variations from normal
|
76 |
-
- Specific measurements or quantitative observations if applicable
|
77 |
-
## 3. CLINICAL INTERPRETATION
|
78 |
-
- Significance of the findings
|
79 |
-
- Differential diagnostic considerations
|
80 |
-
- Correlation with provided clinical history
|
81 |
-
## 4. RECOMMENDATIONS
|
82 |
-
- Suggested next steps or additional imaging
|
83 |
-
- Clinical correlation recommendations
|
84 |
-
- Follow-up suggestions
|
85 |
-
## 5. LIMITATIONS & DISCLAIMERS
|
86 |
-
- What cannot be determined from this image alone
|
87 |
-
- Need for clinical correlation and professional evaluation
|
88 |
-
""",
|
89 |
-
"Quick Assessment": """
|
90 |
-
**PROVIDE FOCUSED QUICK ASSESSMENT:**
|
91 |
-
## KEY FINDINGS
|
92 |
-
- Most significant observations
|
93 |
-
- Normal vs abnormal structures
|
94 |
-
## CLINICAL IMPRESSION
|
95 |
-
- Primary considerations based on image
|
96 |
-
- Any urgent findings that require immediate attention
|
97 |
-
## IMMEDIATE RECOMMENDATIONS
|
98 |
-
- Essential next steps
|
99 |
-
- Urgency level assessment
|
100 |
-
## LIMITATIONS
|
101 |
-
- Important caveats about this assessment
|
102 |
-
""",
|
103 |
-
"Educational": """
|
104 |
-
**PROVIDE EDUCATIONAL ANALYSIS:**
|
105 |
-
## LEARNING OBJECTIVES
|
106 |
-
- Key educational points from this case
|
107 |
-
- Important anatomical or pathological concepts
|
108 |
-
## NORMAL vs ABNORMAL
|
109 |
-
- Clear explanation of what's normal in this image
|
110 |
-
- Detailed description of any abnormal findings
|
111 |
-
## CLINICAL CORRELATION
|
112 |
-
- How image findings relate to symptoms/history
|
113 |
-
- Real-world clinical significance
|
114 |
-
## TEACHING PEARLS
|
115 |
-
- Important concepts this case demonstrates
|
116 |
-
- Common pitfalls or considerations
|
117 |
-
"""
|
118 |
-
}
|
119 |
-
focus_instruction = ""
|
120 |
-
if focus_areas and focus_areas.strip():
|
121 |
-
focus_instruction = f"\n**SPECIAL FOCUS AREAS**: Pay particular attention to: {focus_areas}\n"
|
122 |
-
disclaimer = (
|
123 |
-
"**IMPORTANT MEDICAL DISCLAIMER**: This AI-powered analysis is for educational and research purposes only. "
|
124 |
-
"It should never replace professional medical diagnosis, treatment, or consultation with qualified healthcare providers. "
|
125 |
-
"Always seek professional medical advice for any health concerns or medical decisions."
|
126 |
)
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
)
|
134 |
|
135 |
-
|
136 |
-
image: Image.Image,
|
137 |
-
age: str,
|
138 |
-
gender: str,
|
139 |
-
symptoms: str,
|
140 |
-
history: str,
|
141 |
-
medications: str,
|
142 |
-
analysis_type: str,
|
143 |
-
focus_areas: str,
|
144 |
-
progress=gr.Progress()
|
145 |
-
) -> Tuple[str, str, str]:
|
146 |
-
"""Main analysis function using Gemini Vision Pro"""
|
147 |
-
if image is None:
|
148 |
-
return "❌ Please upload an image first.", "", "❌ No image provided"
|
149 |
-
progress(0.1, desc="Connecting to Gemini...")
|
150 |
-
success, status = setup_gemini()
|
151 |
-
if not success:
|
152 |
-
return status, "", status
|
153 |
-
try:
|
154 |
-
progress(0.3, desc="Preparing analysis...")
|
155 |
-
clinical_data = {
|
156 |
-
"age": age.strip(),
|
157 |
-
"gender": gender,
|
158 |
-
"symptoms": symptoms.strip(),
|
159 |
-
"history": history.strip(),
|
160 |
-
"medications": medications.strip()
|
161 |
-
}
|
162 |
-
prompt = create_medical_prompt(clinical_data, analysis_type, focus_areas)
|
163 |
-
progress(0.5, desc="Analyzing image with Gemini...")
|
164 |
-
response = GEMINI_MODEL.generate_content([prompt, image])
|
165 |
-
if not response or not response.text:
|
166 |
-
return "❌ No response received from Gemini API", "", "❌ Analysis failed"
|
167 |
-
progress(0.9, desc="Preparing results...")
|
168 |
-
report_data = {
|
169 |
-
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S UTC"),
|
170 |
-
"model": "Google Gemini-1.5-Pro Vision",
|
171 |
-
"analysis_type": analysis_type,
|
172 |
-
"clinical_data": clinical_data,
|
173 |
-
"focus_areas": focus_areas,
|
174 |
-
"analysis": response.text
|
175 |
-
}
|
176 |
-
download_content = json.dumps(report_data, indent=2)
|
177 |
-
progress(1.0, desc="Analysis complete!")
|
178 |
-
return response.text, download_content, "✅ Analysis completed successfully"
|
179 |
-
except Exception as e:
|
180 |
-
error_msg = f"❌ Analysis failed: {str(e)}"
|
181 |
-
if "API_KEY" in str(e):
|
182 |
-
error_msg += "\n\n💡 Tip: Make sure your Google API key is valid and has access to Gemini API"
|
183 |
-
elif "quota" in str(e).lower():
|
184 |
-
error_msg += "\n\n💡 Tip: You may have exceeded your API quota. Check your Google Cloud Console"
|
185 |
-
elif "safety" in str(e).lower():
|
186 |
-
error_msg += "\n\n💡 Tip: The image may have been blocked by safety filters. Try a different medical image"
|
187 |
-
return error_msg, "", error_msg
|
188 |
-
|
189 |
-
def create_interface():
|
190 |
-
"""Create the Gradio interface for Gemini Vision Pro"""
|
191 |
-
css = """
|
192 |
-
.gradio-container { max-width: 1400px !important; }
|
193 |
-
.medical-header { text-align: center; color: #1a73e8; margin-bottom: 20px; }
|
194 |
-
.status-success { color: #137333; font-weight: 500; }
|
195 |
-
.status-error { color: #d93025; font-weight: 500; }
|
196 |
-
"""
|
197 |
-
with gr.Blocks(css=css, theme=gr.themes.Soft(), title="Gemini Medical AI") as interface:
|
198 |
-
gr.HTML("<h1 class='medical-header'>Gemini Vision Pro Medical Image Analysis</h1><p>*Fast, efficient medical image analysis using Google's latest AI*</p>")
|
199 |
-
with gr.Row():
|
200 |
-
with gr.Column():
|
201 |
-
image_input = gr.Image(type="pil", label="Upload a medical image")
|
202 |
-
age = gr.Textbox(label="Patient Age", placeholder="e.g. 47")
|
203 |
-
gender = gr.Dropdown(choices=["Male", "Female", "Other", "Unknown"], label="Gender", value="Unknown")
|
204 |
-
symptoms = gr.Textbox(label="Symptoms", placeholder="Describe presenting symptoms")
|
205 |
-
history = gr.Textbox(label="Medical History", placeholder="Relevant medical history")
|
206 |
-
medications = gr.Textbox(label="Current Medications", placeholder="List current medications")
|
207 |
-
analysis_type = gr.Radio(
|
208 |
-
choices=["Comprehensive", "Quick Assessment", "Educational"],
|
209 |
-
value="Comprehensive", label="Analysis Type"
|
210 |
-
)
|
211 |
-
focus_areas = gr.Textbox(label="Special Focus Areas", placeholder="e.g. lung nodules, bone lesions")
|
212 |
-
analyze_btn = gr.Button("Analyze Image", variant="primary")
|
213 |
-
with gr.Column():
|
214 |
-
status = gr.Markdown(value="", elem_classes="status-success")
|
215 |
-
output = gr.Markdown(label="AI Medical Analysis")
|
216 |
-
download = gr.DownloadButton(label="Download Report", file_name="analysis_report.json")
|
217 |
-
analyze_btn.click(
|
218 |
-
analyze_medical_image_gemini,
|
219 |
-
inputs=[image_input, age, gender, symptoms, history, medications, analysis_type, focus_areas],
|
220 |
-
outputs=[output, download, status]
|
221 |
-
)
|
222 |
-
return interface
|
223 |
-
|
224 |
if __name__ == "__main__":
|
225 |
-
demo
|
226 |
-
demo.launch()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import gradio as gr
|
2 |
import google.generativeai as genai
|
3 |
from PIL import Image
|
4 |
import json
|
5 |
+
from typing import List, Dict, Any
|
6 |
import os
|
7 |
+
from datetime import datetime
|
8 |
+
|
9 |
+
# Configure Gemini API
|
10 |
+
# You'll need to set this as an environment variable in Hugging Face Spaces
|
11 |
+
GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
|
12 |
+
|
13 |
+
class MedicalAssistant:
|
14 |
+
def __init__(self):
|
15 |
+
if not GOOGLE_API_KEY:
|
16 |
+
raise ValueError("Please set GOOGLE_API_KEY environment variable")
|
17 |
+
|
18 |
+
genai.configure(api_key=GOOGLE_API_KEY)
|
19 |
+
|
20 |
+
# Use Gemini Pro Vision for multimodal capabilities
|
21 |
+
self.model = genai.GenerativeModel('gemini-1.5-pro-latest')
|
22 |
+
|
23 |
+
# Medical analysis prompt template
|
24 |
+
self.medical_prompt_template = """
|
25 |
+
You are an expert medical AI assistant with comprehensive training in medical imaging, diagnostics, and clinical decision support. Your analysis should be thorough, evidence-based, and clinically relevant.
|
26 |
+
|
27 |
+
**IMPORTANT DISCLAIMERS:**
|
28 |
+
- This analysis is for educational and assistive purposes only
|
29 |
+
- It does not replace professional medical consultation
|
30 |
+
- All findings should be verified by qualified healthcare providers
|
31 |
+
- Emergency cases require immediate medical attention
|
32 |
+
|
33 |
+
**PATIENT INFORMATION:**
|
34 |
+
{patient_info}
|
35 |
+
|
36 |
+
**CHIEF COMPLAINTS:**
|
37 |
+
{complaints}
|
38 |
+
|
39 |
+
**MEDICAL IMAGES PROVIDED:**
|
40 |
+
{image_count} image(s) uploaded for analysis
|
41 |
+
|
42 |
+
**TASK:**
|
43 |
+
Please provide a comprehensive medical analysis including:
|
44 |
+
|
45 |
+
1. **IMAGE ANALYSIS** (if images provided):
|
46 |
+
- Systematic description of visible findings
|
47 |
+
- Anatomical structures identified
|
48 |
+
- Any abnormalities, lesions, or pathological changes
|
49 |
+
- Image quality and limitations assessment
|
50 |
+
|
51 |
+
2. **CLINICAL CORRELATION:**
|
52 |
+
- How imaging findings relate to patient symptoms
|
53 |
+
- Differential diagnoses based on presentation
|
54 |
+
- Risk factors and red flags identified
|
55 |
+
|
56 |
+
3. **DIFFERENTIAL DIAGNOSES:**
|
57 |
+
- List 3-5 most likely diagnoses with reasoning
|
58 |
+
- Include probability assessment if possible
|
59 |
+
- Consider both common and critical conditions
|
60 |
+
|
61 |
+
4. **RECOMMENDED INVESTIGATIONS:**
|
62 |
+
- Additional imaging studies if needed
|
63 |
+
- Laboratory tests to consider
|
64 |
+
- Specialist consultations advised
|
65 |
+
|
66 |
+
5. **IMMEDIATE CONCERNS:**
|
67 |
+
- Any findings requiring urgent attention
|
68 |
+
- Red flags or emergency indicators
|
69 |
+
|
70 |
+
6. **MANAGEMENT SUGGESTIONS:**
|
71 |
+
- Initial treatment considerations
|
72 |
+
- Follow-up recommendations
|
73 |
+
- Patient education points
|
74 |
+
|
75 |
+
7. **LIMITATIONS & CONSIDERATIONS:**
|
76 |
+
- Limitations of the current analysis
|
77 |
+
- Information gaps that need addressing
|
78 |
+
- Quality of provided data
|
79 |
+
|
80 |
+
Please structure your response clearly with appropriate medical terminology while ensuring it's understandable. Use evidence-based medicine principles and cite relevant clinical guidelines where applicable.
|
81 |
+
|
82 |
+
Remember to maintain a professional, empathetic tone and emphasize the importance of professional medical consultation for definitive diagnosis and treatment.
|
83 |
+
"""
|
84 |
+
|
85 |
+
def format_patient_info(self, age, gender, medical_history, current_medications, allergies, vital_signs):
|
86 |
+
"""Format patient information for the prompt"""
|
87 |
+
info = []
|
88 |
+
if age:
|
89 |
+
info.append(f"Age: {age}")
|
90 |
+
if gender:
|
91 |
+
info.append(f"Gender: {gender}")
|
92 |
+
if medical_history:
|
93 |
+
info.append(f"Medical History: {medical_history}")
|
94 |
+
if current_medications:
|
95 |
+
info.append(f"Current Medications: {current_medications}")
|
96 |
+
if allergies:
|
97 |
+
info.append(f"Allergies: {allergies}")
|
98 |
+
if vital_signs:
|
99 |
+
info.append(f"Vital Signs: {vital_signs}")
|
100 |
+
|
101 |
+
return "\n".join(info) if info else "No patient information provided"
|
102 |
+
|
103 |
+
def analyze_medical_case(self, images, age, gender, medical_history,
|
104 |
+
current_medications, allergies, vital_signs, complaints):
|
105 |
+
"""Analyze medical case with Gemini"""
|
106 |
+
try:
|
107 |
+
# Format patient information
|
108 |
+
patient_info = self.format_patient_info(
|
109 |
+
age, gender, medical_history, current_medications,
|
110 |
+
allergies, vital_signs
|
111 |
+
)
|
112 |
+
|
113 |
+
# Prepare the prompt
|
114 |
+
prompt = self.medical_prompt_template.format(
|
115 |
+
patient_info=patient_info,
|
116 |
+
complaints=complaints if complaints else "No specific complaints provided",
|
117 |
+
image_count=len(images) if images else 0
|
118 |
+
)
|
119 |
+
|
120 |
+
# Prepare content for Gemini
|
121 |
+
content = [prompt]
|
122 |
+
|
123 |
+
# Add images if provided
|
124 |
+
if images:
|
125 |
+
for img_path in images:
|
126 |
+
try:
|
127 |
+
img = Image.open(img_path)
|
128 |
+
content.append(img)
|
129 |
+
except Exception as e:
|
130 |
+
return f"Error loading image {img_path}: {str(e)}"
|
131 |
+
|
132 |
+
# Generate response
|
133 |
+
response = self.model.generate_content(content)
|
134 |
+
|
135 |
+
# Add timestamp and disclaimer
|
136 |
+
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
137 |
+
output = f"**Analysis Generated on: {timestamp}**\n\n"
|
138 |
+
output += "⚠️ **MEDICAL DISCLAIMER**: This is an AI-generated analysis for educational purposes only. "
|
139 |
+
output += "It is not a substitute for professional medical advice, diagnosis, or treatment. "
|
140 |
+
output += "Always seek the advice of qualified healthcare providers.\n\n"
|
141 |
+
output += "---\n\n"
|
142 |
+
output += response.text
|
143 |
+
|
144 |
+
return output
|
145 |
+
|
146 |
+
except Exception as e:
|
147 |
+
return f"Error during analysis: {str(e)}\n\nPlease check your API key and inputs."
|
148 |
+
|
149 |
+
# Initialize the assistant
|
150 |
+
assistant = MedicalAssistant()
|
151 |
+
|
152 |
+
# Create Gradio interface
|
153 |
+
def process_medical_case(images, age, gender, medical_history,
|
154 |
+
current_medications, allergies, vital_signs, complaints):
|
155 |
+
"""Process medical case through Gradio interface"""
|
156 |
+
|
157 |
+
# Validate inputs
|
158 |
+
if not complaints and not images:
|
159 |
+
return "Please provide either medical images or patient complaints for analysis."
|
160 |
+
|
161 |
+
# Get image paths if images uploaded
|
162 |
+
image_paths = []
|
163 |
+
if images:
|
164 |
+
if isinstance(images, list):
|
165 |
+
image_paths = [img.name if hasattr(img, 'name') else img for img in images]
|
166 |
else:
|
167 |
+
image_paths = [images.name if hasattr(images, 'name') else images]
|
168 |
+
|
169 |
+
# Run analysis
|
170 |
+
result = assistant.analyze_medical_case(
|
171 |
+
image_paths, age, gender, medical_history,
|
172 |
+
current_medications, allergies, vital_signs, complaints
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
173 |
)
|
174 |
+
|
175 |
+
return result
|
176 |
+
|
177 |
+
# Create Gradio interface
|
178 |
+
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
179 |
+
gr.Markdown(
|
180 |
+
"""
|
181 |
+
# 🏥 Medical AI Assistant powered by Gemini
|
182 |
+
|
183 |
+
This AI assistant analyzes medical images and patient data to provide clinical insights.
|
184 |
+
Upload medical images and enter patient information for comprehensive analysis.
|
185 |
+
|
186 |
+
**Note**: Ensure you have set the GOOGLE_API_KEY environment variable in your Hugging Face Space settings.
|
187 |
+
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
)
|
189 |
+
|
190 |
+
with gr.Row():
|
191 |
+
with gr.Column(scale=1):
|
192 |
+
gr.Markdown("### 📋 Patient Information")
|
193 |
+
age = gr.Number(label="Age", precision=0)
|
194 |
+
gender = gr.Dropdown(
|
195 |
+
label="Gender",
|
196 |
+
choices=["Male", "Female", "Other", "Prefer not to say"],
|
197 |
+
value="Prefer not to say"
|
198 |
+
)
|
199 |
+
medical_history = gr.Textbox(
|
200 |
+
label="Medical History",
|
201 |
+
placeholder="Previous diagnoses, surgeries, chronic conditions...",
|
202 |
+
lines=3
|
203 |
+
)
|
204 |
+
current_medications = gr.Textbox(
|
205 |
+
label="Current Medications",
|
206 |
+
placeholder="List all current medications and dosages...",
|
207 |
+
lines=2
|
208 |
+
)
|
209 |
+
allergies = gr.Textbox(
|
210 |
+
label="Allergies",
|
211 |
+
placeholder="Drug allergies, food allergies, etc...",
|
212 |
+
lines=2
|
213 |
+
)
|
214 |
+
vital_signs = gr.Textbox(
|
215 |
+
label="Vital Signs",
|
216 |
+
placeholder="BP: 120/80, HR: 72, Temp: 98.6°F, etc...",
|
217 |
+
lines=2
|
218 |
+
)
|
219 |
+
|
220 |
+
with gr.Column(scale=1):
|
221 |
+
gr.Markdown("### 🏥 Clinical Data")
|
222 |
+
complaints = gr.Textbox(
|
223 |
+
label="Chief Complaints & Symptoms",
|
224 |
+
placeholder="Describe main symptoms, duration, severity, associated factors...",
|
225 |
+
lines=6
|
226 |
+
)
|
227 |
+
images = gr.File(
|
228 |
+
label="Medical Images",
|
229 |
+
file_count="multiple",
|
230 |
+
file_types=["image"],
|
231 |
+
type="filepath"
|
232 |
+
)
|
233 |
+
gr.Markdown(
|
234 |
+
"""
|
235 |
+
**Supported formats**: X-rays, CT scans, MRI, ultrasound, clinical photos
|
236 |
+
|
237 |
+
**Privacy Note**: Ensure all images are properly anonymized
|
238 |
+
"""
|
239 |
+
)
|
240 |
+
|
241 |
+
submit_btn = gr.Button("🔬 Analyze Case", variant="primary", size="lg")
|
242 |
+
|
243 |
+
output = gr.Markdown(label="Analysis Results")
|
244 |
+
|
245 |
+
# Examples
|
246 |
+
gr.Examples(
|
247 |
+
examples=[
|
248 |
+
[
|
249 |
+
None, # images
|
250 |
+
45, # age
|
251 |
+
"Male", # gender
|
252 |
+
"Hypertension for 5 years, Type 2 diabetes", # medical history
|
253 |
+
"Metformin 500mg BD, Amlodipine 5mg OD", # medications
|
254 |
+
"None known", # allergies
|
255 |
+
"BP: 140/90, HR: 78, RR: 16", # vital signs
|
256 |
+
"Chest pain for 2 days, radiating to left arm, associated with shortness of breath" # complaints
|
257 |
+
],
|
258 |
+
[
|
259 |
+
None,
|
260 |
+
28,
|
261 |
+
"Female",
|
262 |
+
"Migraine headaches",
|
263 |
+
"None",
|
264 |
+
"Penicillin - rash",
|
265 |
+
"BP: 110/70, HR: 68",
|
266 |
+
"Severe headache, photophobia, nausea for 6 hours"
|
267 |
+
]
|
268 |
+
],
|
269 |
+
inputs=[images, age, gender, medical_history, current_medications,
|
270 |
+
allergies, vital_signs, complaints]
|
271 |
+
)
|
272 |
+
|
273 |
+
submit_btn.click(
|
274 |
+
fn=process_medical_case,
|
275 |
+
inputs=[images, age, gender, medical_history, current_medications,
|
276 |
+
allergies, vital_signs, complaints],
|
277 |
+
outputs=output
|
278 |
+
)
|
279 |
+
|
280 |
+
gr.Markdown(
|
281 |
+
"""
|
282 |
+
---
|
283 |
+
### ⚕️ Important Information:
|
284 |
+
- This tool is for educational and assistive purposes only
|
285 |
+
- Always consult qualified healthcare professionals for medical decisions
|
286 |
+
- Ensure patient privacy and HIPAA compliance when using this tool
|
287 |
+
- Report any issues or feedback to improve the system
|
288 |
+
|
289 |
+
### 🔧 Setup Instructions for Hugging Face:
|
290 |
+
1. Create a Space on Hugging Face
|
291 |
+
2. Add your Google API key as a secret: GOOGLE_API_KEY
|
292 |
+
3. Install requirements: `google-generativeai gradio pillow`
|
293 |
+
4. Deploy this code
|
294 |
+
"""
|
295 |
)
|
296 |
|
297 |
+
# Launch the app
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
298 |
if __name__ == "__main__":
|
299 |
+
demo.launch()
|
|