Spaces:
Running
Running
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() |