File size: 12,146 Bytes
f81ca4e
d93af2a
acc2ddd
f81ca4e
184ee6c
d93af2a
184ee6c
 
 
 
 
 
 
 
 
 
 
f81ca4e
 
 
d93af2a
 
 
 
f81ca4e
d93af2a
 
 
f81ca4e
 
d93af2a
a5da8f2
f81ca4e
d93af2a
184ee6c
 
d93af2a
 
a5da8f2
d93af2a
 
f81ca4e
d93af2a
a7e7c33
a5da8f2
d93af2a
 
f81ca4e
 
 
d93af2a
 
 
 
f81ca4e
 
 
d93af2a
 
 
 
 
f81ca4e
 
d93af2a
f81ca4e
 
a7e7c33
 
 
 
 
 
 
 
 
d93af2a
 
 
 
 
 
f81ca4e
a7e7c33
 
 
f81ca4e
 
d93af2a
 
a7e7c33
 
 
d93af2a
a7e7c33
d93af2a
a7e7c33
e63aeb2
 
a7e7c33
 
 
 
 
 
 
 
 
d93af2a
 
 
f81ca4e
 
d93af2a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a7e7c33
 
 
 
 
 
 
 
 
 
d93af2a
 
 
 
f81ca4e
 
 
 
 
 
 
d93af2a
f81ca4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d93af2a
f81ca4e
 
d93af2a
f81ca4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d93af2a
f81ca4e
 
d93af2a
f81ca4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d93af2a
f81ca4e
d93af2a
f81ca4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
acc2ddd
f81ca4e
1
2
3
4
5
6
7
8
9
10
11
12
13
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
import gradio as gr
import os
import requests
import re
import logging
from huggingface_hub import InferenceClient

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.StreamHandler(),
        logging.FileHandler('medgemma_app.log')
    ]
)
logger = logging.getLogger(__name__)

class MedGemmaSymptomAnalyzer:
    def __init__(self):
        self.client = None
        self.model_name = "google/medgemma-4b-it"
        self.api_connected = False
        logger.info("Initializing MedGemma Symptom Analyzer with HuggingFace Inference API...")
    
    def connect_to_api(self):
        """Connect to HuggingFace Inference API"""
        if self.api_connected:
            return True
            
        logger.info("Connecting to HuggingFace Inference API...")
        
        try:
            # Get HF token from environment or use provided token
            hf_token = os.getenv("HF_TOKEN")
            
            if hf_token:
                logger.info("Using HuggingFace token for API authentication")
            else:
                logger.warning("No HuggingFace token found")
                return False
            
            # Initialize the InferenceClient
            self.client = InferenceClient(provider="auto",token=hf_token)
            
            self.api_connected = True
            logger.info("✅ Connected to HuggingFace Inference API successfully!")
            return True
                
        except Exception as e:
            logger.error(f"Failed to connect to HuggingFace API: {str(e)}")
            logger.warning("Falling back to demo mode due to API connection failure")
            self.client = None
            self.api_connected = False
            return False
    
    def analyze_symptoms(self, symptoms_text, max_length=512, temperature=0.7):
        """Analyze symptoms using HuggingFace Inference API"""
        # Try to connect to API if not already connected
        if not self.api_connected:
            if not self.connect_to_api():
                # Fallback to demo response if API connection fails
                return self._get_demo_response(symptoms_text)
        
        if not self.client:
            return self._get_demo_response(symptoms_text)
        
        # Format message for conversational API
        messages = [
            {
                "role": "system", 
                "content": """You are an expert medical AI assistant trained to analyze symptoms and provide comprehensive medical insights. Always provide structured analysis with clear sections for differential diagnoses, next steps, red flags, and general care recommendations."""
            },
            {
                "role": "user",
                "content": f"""Patient presents with the following symptoms: {symptoms_text}

Based on these symptoms, provide a comprehensive medical analysis including:
1. **Possible Differential Diagnoses**: List the most likely conditions based on the symptoms
2. **Recommended Next Steps**: Suggest appropriate diagnostic tests or evaluations  
3. **When to Seek Immediate Medical Attention**: Identify red flags requiring urgent care
4. **General Care Recommendations**: Provide supportive care and lifestyle advice

Please provide a detailed medical analysis:"""
            }
        ]
        
        try:
            logger.info("Sending request to HuggingFace Inference API...")
            
            # Make API call using chat completion (conversational)
            response = self.client.chat_completion(
                messages=messages,
                model=self.model_name,
                max_tokens=max_length,
                temperature=temperature,
                stream=False
            )
            
            # Extract response text
            if response and response.choices and len(response.choices) > 0:
                response_text = response.choices[0].message.content
                if response_text:
                    logger.info("✅ Successfully received response from API")
                    return response_text
                else:
                    logger.warning("No content in response from API")
                    return self._get_demo_response(symptoms_text)
            else:
                logger.warning("No response received from API")
                return self._get_demo_response(symptoms_text)
            
        except Exception as e:
            error_msg = str(e)
            logger.error(f"Error during API analysis: {error_msg}")
            
            # Provide specific error messages for common issues
            if "404" in error_msg and "medgemma" in error_msg.lower():
                logger.warning("MedGemma model may require special access approval (gated model)")
                return f"""**API ACCESS REQUIRED**

The MedGemma model appears to require special access approval from Google/HuggingFace. 

To use the actual MedGemma model:
1. Visit: https://huggingface.co/google/medgemma-4b-it
2. Request access to the gated model
3. Wait for approval from Google
4. Ensure your HuggingFace token has the necessary permissions

**Current Status**: Using demo mode while waiting for model access.

{self._get_demo_response(symptoms_text)}"""
            elif "not supported for task" in error_msg:
                logger.warning("Model task mismatch - trying alternative approach")
                return f"""**API CONFIGURATION ISSUE**

The MedGemma model configuration has changed. The error indicates:
{error_msg}

**Current Status**: Using demo mode while API configuration is resolved.

{self._get_demo_response(symptoms_text)}"""
            else:
                # Fallback to demo response on API error
                return self._get_demo_response(symptoms_text)
    
    def _get_demo_response(self, symptoms_text):
        """Provide a demo response when model is not available"""
        symptoms_lower = symptoms_text.lower()
        
        # Simple keyword-based demo responses
        if any(word in symptoms_lower for word in ['fever', 'headache', 'fatigue', 'body aches']):
            return """**DEMO MODE - API not connected**

Based on the symptoms described (fever, headache, fatigue), here's a general analysis:

**Possible Differential Diagnoses:**
1. Viral infection (common cold, flu)
2. Bacterial infection
3. Stress or exhaustion
4. Early signs of other conditions

**Recommended Next Steps:**
1. Rest and adequate hydration
2. Monitor temperature regularly
3. Over-the-counter pain relievers if appropriate
4. Observe for worsening symptoms

**When to Seek Immediate Medical Attention:**
- High fever (>101.3°F/38.5°C)
- Severe headache or neck stiffness
- Difficulty breathing
- Persistent vomiting
- Symptoms worsen rapidly

*Note: This is a demo response. For actual medical analysis, the HuggingFace Inference API needs to be connected.*"""
        
        elif any(word in symptoms_lower for word in ['chest pain', 'breathing', 'shortness']):
            return """**DEMO MODE - API not connected**

Based on chest-related symptoms, here's a general analysis:

**Possible Differential Diagnoses:**
1. Respiratory infection
2. Muscle strain
3. Anxiety-related symptoms
4. More serious conditions requiring evaluation

**Recommended Next Steps:**
1. Seek medical evaluation promptly
2. Avoid strenuous activity
3. Monitor breathing patterns
4. Note any associated symptoms

**When to Seek Immediate Medical Attention:**
- Severe chest pain
- Difficulty breathing
- Pain spreading to arm, jaw, or back
- Dizziness or fainting
- These symptoms require immediate medical care

*Note: This is a demo response. For actual medical analysis, the HuggingFace Inference API needs to be connected.*"""
        
        else:
            return f"""**DEMO MODE - API not connected**

Thank you for describing your symptoms. In demo mode, I can provide general guidance:

**General Recommendations:**
1. Keep track of when symptoms started
2. Note any factors that make symptoms better or worse
3. Stay hydrated and get adequate rest
4. Consider consulting a healthcare provider

**When to Seek Medical Attention:**
- Symptoms persist or worsen
- You develop new concerning symptoms
- You have underlying health conditions
- You're unsure about the severity

For a proper AI-powered analysis of your specific symptoms: "{symptoms_text[:100]}...", the HuggingFace Inference API would need to be successfully connected.

*Note: This is a demo response. For actual medical analysis, the HuggingFace Inference API needs to be connected.*"""

# Initialize the analyzer
analyzer = MedGemmaSymptomAnalyzer()

def analyze_symptoms_interface(symptoms, temperature):
    """Interface function for Gradio"""
    if not symptoms.strip():
        return "Please enter some symptoms to analyze."
    
    # Add medical disclaimer
    disclaimer = """⚠️ **MEDICAL DISCLAIMER**: This analysis is for educational purposes only and should not replace professional medical advice. Always consult with a healthcare provider for proper diagnosis and treatment.

"""
    
    analysis = analyzer.analyze_symptoms(symptoms, temperature=temperature)
    return disclaimer + analysis

# Create Gradio interface
with gr.Blocks(title="MedGemma Symptom Analyzer", theme=gr.themes.Soft()) as demo:
    gr.Markdown("""
    # 🏥 MedGemma Symptom Analyzer
    
    This application uses Google's MedGemma model to provide preliminary analysis of medical symptoms. 
    Enter your symptoms below to get AI-powered insights.
    
    **Important**: This tool is for educational purposes only and should not replace professional medical advice.
    """)
    
    with gr.Row():
        with gr.Column(scale=2):
            symptoms_input = gr.Textbox(
                label="Describe your symptoms",
                placeholder="Example: I have been experiencing headaches, fever, and fatigue for the past 3 days...",
                lines=5,
                max_lines=10
            )
            
            temperature_slider = gr.Slider(
                minimum=0.1,
                maximum=1.0,
                value=0.7,
                step=0.1,
                label="Response Creativity (Temperature)",
                info="Lower values = more focused, Higher values = more creative"
            )
            
            analyze_btn = gr.Button("🔍 Analyze Symptoms", variant="primary")
            
        with gr.Column(scale=3):
            output = gr.Textbox(
                label="Medical Analysis",
                lines=15,
                max_lines=20,
                interactive=False
            )
    
    # Example symptoms
    gr.Markdown("### 📝 Example Symptoms to Try:")
    with gr.Row():
        example1 = gr.Button("Flu-like symptoms", size="sm")
        example2 = gr.Button("Chest pain", size="sm")
        example3 = gr.Button("Digestive issues", size="sm")
    
    # Event handlers
    analyze_btn.click(
        analyze_symptoms_interface,
        inputs=[symptoms_input, temperature_slider],
        outputs=output
    )
    
    example1.click(
        lambda: "I have been experiencing fever, body aches, headache, and fatigue for the past 2 days. I also have a slight cough.",
        outputs=symptoms_input
    )
    
    example2.click(
        lambda: "I'm experiencing chest pain that worsens when I take deep breaths. It started this morning and is accompanied by shortness of breath.",
        outputs=symptoms_input
    )
    
    example3.click(
        lambda: "I have been having stomach pain, nausea, and diarrhea for the past day. I also feel bloated and have lost my appetite.",
        outputs=symptoms_input
    )
    
    gr.Markdown("""
    ### ⚠️ Important Notes:
    - This is an AI tool for educational purposes only
    - Always consult healthcare professionals for medical concerns
    - Seek immediate medical attention for severe or emergency symptoms
    - The AI may not always provide accurate medical information
    """)

if __name__ == "__main__":
    demo.launch()