Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
#!/usr/bin/env python3
|
2 |
"""
|
3 |
Gemini Vision Pro Medical Image Analysis - Gradio Interface
|
4 |
-
|
5 |
"""
|
6 |
|
7 |
import gradio as gr
|
@@ -20,36 +20,127 @@ warnings.filterwarnings("ignore")
|
|
20 |
GEMINI_MODEL = None
|
21 |
API_KEY = None
|
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
def setup_gemini(api_key: str = None):
|
24 |
"""Setup Gemini Vision Pro with API key"""
|
25 |
global GEMINI_MODEL, API_KEY
|
26 |
|
27 |
-
# Try to get API key from
|
28 |
-
if api_key:
|
29 |
-
API_KEY = api_key
|
30 |
else:
|
31 |
-
API_KEY =
|
32 |
|
33 |
if not API_KEY:
|
34 |
-
return False, "β No API key
|
35 |
|
36 |
try:
|
37 |
# Configure the API
|
38 |
genai.configure(api_key=API_KEY)
|
39 |
|
40 |
-
# Initialize the model
|
41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
|
43 |
-
|
44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
|
46 |
if test_response and test_response.text:
|
47 |
return True, "β
Gemini Vision Pro connected successfully!"
|
48 |
else:
|
49 |
-
return False, "β Failed to
|
50 |
|
51 |
except Exception as e:
|
52 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
|
54 |
def create_medical_prompt(clinical_data: Dict, analysis_type: str, focus_areas: str) -> str:
|
55 |
"""Create optimized medical analysis prompt for Gemini"""
|
@@ -59,10 +150,11 @@ def create_medical_prompt(clinical_data: Dict, analysis_type: str, focus_areas:
|
|
59 |
**ANALYSIS INSTRUCTIONS:**
|
60 |
Analyze this medical image systematically and professionally:
|
61 |
- Use clear medical terminology with explanations for complex terms
|
62 |
-
- Structure your response with clear sections and headers
|
63 |
- Be thorough but concise
|
64 |
- Always mention limitations and emphasize the need for professional medical consultation
|
65 |
- Focus on observable findings rather than definitive diagnoses
|
|
|
66 |
"""
|
67 |
|
68 |
# Add clinical context if provided
|
@@ -185,11 +277,11 @@ def analyze_medical_image_gemini(
|
|
185 |
|
186 |
# Prepare clinical data
|
187 |
clinical_data = {
|
188 |
-
"age": age.strip(),
|
189 |
-
"gender": gender,
|
190 |
-
"symptoms": symptoms.strip(),
|
191 |
-
"history": history.strip(),
|
192 |
-
"medications": medications.strip()
|
193 |
}
|
194 |
|
195 |
# Create prompt
|
@@ -197,11 +289,22 @@ def analyze_medical_image_gemini(
|
|
197 |
|
198 |
progress(0.5, desc="Analyzing image with Gemini...")
|
199 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
# Generate analysis using Gemini Vision Pro
|
201 |
-
response = GEMINI_MODEL.generate_content(
|
|
|
|
|
|
|
202 |
|
203 |
if not response or not response.text:
|
204 |
-
return "β No response received from Gemini API", "", "β Analysis failed"
|
205 |
|
206 |
progress(0.9, desc="Preparing results...")
|
207 |
|
@@ -211,7 +314,7 @@ def analyze_medical_image_gemini(
|
|
211 |
"model": "Google Gemini-1.5-Pro Vision",
|
212 |
"analysis_type": analysis_type,
|
213 |
"clinical_data": clinical_data,
|
214 |
-
"focus_areas": focus_areas,
|
215 |
"analysis": response.text
|
216 |
}
|
217 |
|
@@ -223,12 +326,22 @@ def analyze_medical_image_gemini(
|
|
223 |
|
224 |
except Exception as e:
|
225 |
error_msg = f"β Analysis failed: {str(e)}"
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
error_msg += "\n\nπ‘
|
230 |
-
|
231 |
-
error_msg += "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
232 |
|
233 |
return error_msg, "", error_msg
|
234 |
|
@@ -260,6 +373,13 @@ def create_interface():
|
|
260 |
color: #d93025;
|
261 |
font-weight: 500;
|
262 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
263 |
"""
|
264 |
|
265 |
with gr.Blocks(css=css, theme=gr.themes.Soft(), title="Gemini Medical AI") as interface:
|
@@ -273,23 +393,45 @@ def create_interface():
|
|
273 |
</div>
|
274 |
""")
|
275 |
|
|
|
|
|
|
|
276 |
# API Configuration Section
|
277 |
-
with gr.Accordion("π API Configuration", open=
|
278 |
-
|
279 |
-
|
280 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
281 |
""")
|
282 |
|
283 |
api_key_input = gr.Textbox(
|
284 |
-
label="Google API Key",
|
285 |
type="password",
|
286 |
-
placeholder="Enter your Google API key here...",
|
287 |
-
info="
|
|
|
288 |
)
|
289 |
|
290 |
status_display = gr.Textbox(
|
291 |
label="Connection Status",
|
292 |
-
value="β³ Enter API key to connect",
|
293 |
interactive=False
|
294 |
)
|
295 |
|
@@ -382,6 +524,30 @@ def create_interface():
|
|
382 |
download_content = gr.Textbox(visible=False)
|
383 |
|
384 |
# Information sections
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
385 |
with gr.Accordion("π‘ About Gemini Vision Pro", open=False):
|
386 |
gr.Markdown("""
|
387 |
### π **Advantages of Gemini Vision Pro:**
|
@@ -405,21 +571,6 @@ def create_interface():
|
|
405 |
- Check [Google AI Pricing](https://ai.google.dev/pricing) for current rates
|
406 |
""")
|
407 |
|
408 |
-
with gr.Accordion("π Tips for Better Results", open=False):
|
409 |
-
gr.Markdown("""
|
410 |
-
### π― **Optimization Tips:**
|
411 |
-
- **Provide clinical context**: Age, symptoms, and history significantly improve accuracy
|
412 |
-
- **Use specific focus areas**: "cardiac silhouette, pulmonary vessels" vs just "chest"
|
413 |
-
- **High-quality images**: Clear, well-lit, properly oriented images work best
|
414 |
-
- **Appropriate image size**: Gemini works well with various image sizes
|
415 |
-
- **Choose right analysis type**: Comprehensive for complex cases, Quick for screening
|
416 |
-
|
417 |
-
### π **API Key Security:**
|
418 |
-
- Your API key is only used for this session and not stored
|
419 |
-
- Consider using environment variables for production deployments
|
420 |
-
- Monitor your API usage in Google Cloud Console
|
421 |
-
""")
|
422 |
-
|
423 |
# Footer
|
424 |
gr.HTML("""
|
425 |
<div style="text-align: center; margin-top: 20px; padding: 15px; background-color: #fff3cd; border-radius: 8px;">
|
@@ -438,12 +589,22 @@ def create_interface():
|
|
438 |
return gr.File(value=filename, visible=True)
|
439 |
return gr.File(visible=False)
|
440 |
|
441 |
-
def test_api_connection(
|
442 |
-
if
|
443 |
-
|
444 |
-
success, status = setup_gemini(
|
445 |
return status
|
446 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
447 |
# API key testing
|
448 |
api_key_input.change(
|
449 |
fn=test_api_connection,
|
@@ -469,6 +630,15 @@ def create_interface():
|
|
469 |
|
470 |
if __name__ == "__main__":
|
471 |
print("π₯ Initializing Gemini Medical AI Analyzer...")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
472 |
print("π No local model loading required - using Google Gemini Vision Pro API")
|
473 |
|
474 |
# Create and launch interface
|
|
|
1 |
#!/usr/bin/env python3
|
2 |
"""
|
3 |
Gemini Vision Pro Medical Image Analysis - Gradio Interface
|
4 |
+
Fixed version with HuggingFace Secrets support and better error handling
|
5 |
"""
|
6 |
|
7 |
import gradio as gr
|
|
|
20 |
GEMINI_MODEL = None
|
21 |
API_KEY = None
|
22 |
|
23 |
+
def get_api_key_from_secrets():
|
24 |
+
"""Try to get API key from HuggingFace secrets or environment variables"""
|
25 |
+
# Try multiple possible secret names
|
26 |
+
possible_keys = [
|
27 |
+
'GOOGLE_API_KEY',
|
28 |
+
'GEMINI_API_KEY',
|
29 |
+
'GOOGLE_GEMINI_API_KEY',
|
30 |
+
'GOOGLE_AI_API_KEY'
|
31 |
+
]
|
32 |
+
|
33 |
+
for key_name in possible_keys:
|
34 |
+
# First try HuggingFace secrets (if running on HF Spaces)
|
35 |
+
try:
|
36 |
+
from huggingface_hub import HfFolder
|
37 |
+
token = HfFolder.get_token()
|
38 |
+
if token:
|
39 |
+
# This is a simplified approach - in HF Spaces, secrets are usually available as env vars
|
40 |
+
api_key = os.getenv(key_name)
|
41 |
+
if api_key:
|
42 |
+
return api_key
|
43 |
+
except:
|
44 |
+
pass
|
45 |
+
|
46 |
+
# Try regular environment variables
|
47 |
+
api_key = os.getenv(key_name)
|
48 |
+
if api_key:
|
49 |
+
return api_key
|
50 |
+
|
51 |
+
return None
|
52 |
+
|
53 |
def setup_gemini(api_key: str = None):
|
54 |
"""Setup Gemini Vision Pro with API key"""
|
55 |
global GEMINI_MODEL, API_KEY
|
56 |
|
57 |
+
# Try to get API key from various sources
|
58 |
+
if api_key and api_key.strip():
|
59 |
+
API_KEY = api_key.strip()
|
60 |
else:
|
61 |
+
API_KEY = get_api_key_from_secrets()
|
62 |
|
63 |
if not API_KEY:
|
64 |
+
return False, "β No API key found. Please:\n1. Set GOOGLE_API_KEY in HuggingFace Spaces secrets, or\n2. Enter your API key in the interface below\n\nπ Get your API key from: https://makersuite.google.com/app/apikey"
|
65 |
|
66 |
try:
|
67 |
# Configure the API
|
68 |
genai.configure(api_key=API_KEY)
|
69 |
|
70 |
+
# Initialize the model with safety settings
|
71 |
+
safety_settings = [
|
72 |
+
{
|
73 |
+
"category": "HARM_CATEGORY_MEDICAL",
|
74 |
+
"threshold": "BLOCK_NONE"
|
75 |
+
},
|
76 |
+
{
|
77 |
+
"category": "HARM_CATEGORY_HARASSMENT",
|
78 |
+
"threshold": "BLOCK_ONLY_HIGH"
|
79 |
+
},
|
80 |
+
{
|
81 |
+
"category": "HARM_CATEGORY_HATE_SPEECH",
|
82 |
+
"threshold": "BLOCK_ONLY_HIGH"
|
83 |
+
},
|
84 |
+
{
|
85 |
+
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
|
86 |
+
"threshold": "BLOCK_ONLY_HIGH"
|
87 |
+
},
|
88 |
+
{
|
89 |
+
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
|
90 |
+
"threshold": "BLOCK_ONLY_HIGH"
|
91 |
+
}
|
92 |
+
]
|
93 |
|
94 |
+
GEMINI_MODEL = genai.GenerativeModel(
|
95 |
+
'gemini-1.5-pro',
|
96 |
+
safety_settings=safety_settings
|
97 |
+
)
|
98 |
+
|
99 |
+
# Test the connection with a simple query
|
100 |
+
test_response = GEMINI_MODEL.generate_content(
|
101 |
+
"Respond with just 'OK' to confirm you can analyze medical images.",
|
102 |
+
generation_config=genai.types.GenerationConfig(
|
103 |
+
temperature=0.1,
|
104 |
+
max_output_tokens=10
|
105 |
+
)
|
106 |
+
)
|
107 |
|
108 |
if test_response and test_response.text:
|
109 |
return True, "β
Gemini Vision Pro connected successfully!"
|
110 |
else:
|
111 |
+
return False, "β Failed to get response from Gemini API"
|
112 |
|
113 |
except Exception as e:
|
114 |
+
error_msg = f"β Gemini setup failed: {str(e)}"
|
115 |
+
|
116 |
+
# Provide specific guidance based on error type
|
117 |
+
if "429" in str(e) or "quota" in str(e).lower():
|
118 |
+
error_msg += "\n\nπ‘ **Quota Exceeded Solutions:**\n"
|
119 |
+
error_msg += "β’ Check your Google Cloud Console billing\n"
|
120 |
+
error_msg += "β’ Verify your API key has sufficient quota\n"
|
121 |
+
error_msg += "β’ Try again in a few minutes (rate limiting)\n"
|
122 |
+
error_msg += "β’ Consider upgrading your Google AI plan\n"
|
123 |
+
error_msg += "π Check usage: https://console.cloud.google.com/"
|
124 |
+
|
125 |
+
elif "403" in str(e) or "permission" in str(e).lower():
|
126 |
+
error_msg += "\n\nπ‘ **Permission Error Solutions:**\n"
|
127 |
+
error_msg += "β’ Ensure Gemini API is enabled in your project\n"
|
128 |
+
error_msg += "β’ Check if your API key has proper permissions\n"
|
129 |
+
error_msg += "β’ Verify your Google Cloud project settings"
|
130 |
+
|
131 |
+
elif "401" in str(e) or "unauthorized" in str(e).lower():
|
132 |
+
error_msg += "\n\nπ‘ **Authentication Error:**\n"
|
133 |
+
error_msg += "β’ Double-check your API key is correct\n"
|
134 |
+
error_msg += "β’ Ensure no extra spaces in the API key\n"
|
135 |
+
error_msg += "β’ Generate a new API key if needed"
|
136 |
+
|
137 |
+
elif "safety" in str(e).lower() or "blocked" in str(e).lower():
|
138 |
+
error_msg += "\n\nπ‘ **Content Safety Issue:**\n"
|
139 |
+
error_msg += "β’ The image may have triggered safety filters\n"
|
140 |
+
error_msg += "β’ Try a different medical image\n"
|
141 |
+
error_msg += "β’ Ensure the image is clearly medical in nature"
|
142 |
+
|
143 |
+
return False, error_msg
|
144 |
|
145 |
def create_medical_prompt(clinical_data: Dict, analysis_type: str, focus_areas: str) -> str:
|
146 |
"""Create optimized medical analysis prompt for Gemini"""
|
|
|
150 |
**ANALYSIS INSTRUCTIONS:**
|
151 |
Analyze this medical image systematically and professionally:
|
152 |
- Use clear medical terminology with explanations for complex terms
|
153 |
+
- Structure your response with clear sections and headers
|
154 |
- Be thorough but concise
|
155 |
- Always mention limitations and emphasize the need for professional medical consultation
|
156 |
- Focus on observable findings rather than definitive diagnoses
|
157 |
+
- This is for educational and research purposes only
|
158 |
"""
|
159 |
|
160 |
# Add clinical context if provided
|
|
|
277 |
|
278 |
# Prepare clinical data
|
279 |
clinical_data = {
|
280 |
+
"age": age.strip() if age else "",
|
281 |
+
"gender": gender if gender else "",
|
282 |
+
"symptoms": symptoms.strip() if symptoms else "",
|
283 |
+
"history": history.strip() if history else "",
|
284 |
+
"medications": medications.strip() if medications else ""
|
285 |
}
|
286 |
|
287 |
# Create prompt
|
|
|
289 |
|
290 |
progress(0.5, desc="Analyzing image with Gemini...")
|
291 |
|
292 |
+
# Configure generation parameters for better results
|
293 |
+
generation_config = genai.types.GenerationConfig(
|
294 |
+
temperature=0.3, # Lower temperature for more consistent medical analysis
|
295 |
+
max_output_tokens=2048, # Sufficient for detailed analysis
|
296 |
+
top_p=0.8,
|
297 |
+
top_k=40
|
298 |
+
)
|
299 |
+
|
300 |
# Generate analysis using Gemini Vision Pro
|
301 |
+
response = GEMINI_MODEL.generate_content(
|
302 |
+
[prompt, image],
|
303 |
+
generation_config=generation_config
|
304 |
+
)
|
305 |
|
306 |
if not response or not response.text:
|
307 |
+
return "β No response received from Gemini API. The image may have been blocked by safety filters or there was a processing error.", "", "β Analysis failed"
|
308 |
|
309 |
progress(0.9, desc="Preparing results...")
|
310 |
|
|
|
314 |
"model": "Google Gemini-1.5-Pro Vision",
|
315 |
"analysis_type": analysis_type,
|
316 |
"clinical_data": clinical_data,
|
317 |
+
"focus_areas": focus_areas if focus_areas else "None specified",
|
318 |
"analysis": response.text
|
319 |
}
|
320 |
|
|
|
326 |
|
327 |
except Exception as e:
|
328 |
error_msg = f"β Analysis failed: {str(e)}"
|
329 |
+
|
330 |
+
# Provide specific error guidance
|
331 |
+
if "429" in str(e) or "quota" in str(e).lower():
|
332 |
+
error_msg += "\n\nπ‘ **Quota Issue:** You've exceeded your API limits. Please:\n"
|
333 |
+
error_msg += "β’ Check your Google Cloud Console billing\n"
|
334 |
+
error_msg += "β’ Wait a few minutes and try again\n"
|
335 |
+
error_msg += "β’ Consider upgrading your plan"
|
336 |
+
|
337 |
+
elif "safety" in str(e).lower() or "blocked" in str(e).lower():
|
338 |
+
error_msg += "\n\nπ‘ **Safety Filter:** The image was blocked. Try:\n"
|
339 |
+
error_msg += "β’ A different medical image\n"
|
340 |
+
error_msg += "β’ Ensuring the image is clearly medical\n"
|
341 |
+
error_msg += "β’ Removing any potentially sensitive content"
|
342 |
+
|
343 |
+
elif "401" in str(e) or "403" in str(e):
|
344 |
+
error_msg += "\n\nπ‘ **Authentication Error:** Check your API key"
|
345 |
|
346 |
return error_msg, "", error_msg
|
347 |
|
|
|
373 |
color: #d93025;
|
374 |
font-weight: 500;
|
375 |
}
|
376 |
+
.quota-info {
|
377 |
+
background-color: #fff3cd;
|
378 |
+
padding: 10px;
|
379 |
+
border-radius: 5px;
|
380 |
+
margin: 10px 0;
|
381 |
+
border-left: 3px solid #ffc107;
|
382 |
+
}
|
383 |
"""
|
384 |
|
385 |
with gr.Blocks(css=css, theme=gr.themes.Soft(), title="Gemini Medical AI") as interface:
|
|
|
393 |
</div>
|
394 |
""")
|
395 |
|
396 |
+
# Check for existing API key on startup
|
397 |
+
initial_api_key = get_api_key_from_secrets()
|
398 |
+
|
399 |
# API Configuration Section
|
400 |
+
with gr.Accordion("π API Configuration", open=not bool(initial_api_key)):
|
401 |
+
if initial_api_key:
|
402 |
+
gr.Markdown("""
|
403 |
+
### β
API Key Found in Secrets
|
404 |
+
An API key was found in the environment/secrets. You can still override it below if needed.
|
405 |
+
""")
|
406 |
+
else:
|
407 |
+
gr.Markdown("""
|
408 |
+
### π Google Gemini API Setup Required
|
409 |
+
You need a Google API key to use Gemini Vision Pro.
|
410 |
+
|
411 |
+
**For HuggingFace Spaces:** Add your API key as a secret named `GOOGLE_API_KEY`
|
412 |
+
**For local use:** Set the `GOOGLE_API_KEY` environment variable or enter it below
|
413 |
+
|
414 |
+
π Get your API key from: [Google AI Studio](https://makersuite.google.com/app/apikey)
|
415 |
+
""")
|
416 |
+
|
417 |
+
gr.HTML("""
|
418 |
+
<div class="quota-info">
|
419 |
+
<strong>π° Important:</strong> Make sure your Google API key has sufficient quota and billing is set up.
|
420 |
+
The 429 error indicates quota limits have been exceeded.
|
421 |
+
</div>
|
422 |
""")
|
423 |
|
424 |
api_key_input = gr.Textbox(
|
425 |
+
label="Google API Key (Optional Override)",
|
426 |
type="password",
|
427 |
+
placeholder="Enter your Google API key here to override secrets...",
|
428 |
+
info="Leave empty to use API key from secrets/environment",
|
429 |
+
value=""
|
430 |
)
|
431 |
|
432 |
status_display = gr.Textbox(
|
433 |
label="Connection Status",
|
434 |
+
value="β³ Testing connection..." if initial_api_key else "β³ Enter API key to connect",
|
435 |
interactive=False
|
436 |
)
|
437 |
|
|
|
524 |
download_content = gr.Textbox(visible=False)
|
525 |
|
526 |
# Information sections
|
527 |
+
with gr.Accordion("π§ Troubleshooting Common Issues", open=False):
|
528 |
+
gr.Markdown("""
|
529 |
+
### π¨ **Error 429 - Quota Exceeded:**
|
530 |
+
- **Check billing:** Ensure your Google Cloud project has billing enabled
|
531 |
+
- **API limits:** You may have hit free tier limits - consider upgrading
|
532 |
+
- **Rate limiting:** Wait a few minutes and try again
|
533 |
+
- **Multiple keys:** Try generating a new API key
|
534 |
+
|
535 |
+
### π **For HuggingFace Spaces Users:**
|
536 |
+
1. Go to your Space settings
|
537 |
+
2. Add a new secret: `GOOGLE_API_KEY`
|
538 |
+
3. Paste your Google API key as the value
|
539 |
+
4. Restart your Space
|
540 |
+
|
541 |
+
### π **Monitor Usage:**
|
542 |
+
- [Google AI Studio Usage](https://makersuite.google.com/)
|
543 |
+
- [Google Cloud Console](https://console.cloud.google.com/)
|
544 |
+
|
545 |
+
### π **If Still Having Issues:**
|
546 |
+
- Try a different API key
|
547 |
+
- Check if Gemini API is enabled in your project
|
548 |
+
- Verify your Google Cloud project settings
|
549 |
+
""")
|
550 |
+
|
551 |
with gr.Accordion("π‘ About Gemini Vision Pro", open=False):
|
552 |
gr.Markdown("""
|
553 |
### π **Advantages of Gemini Vision Pro:**
|
|
|
571 |
- Check [Google AI Pricing](https://ai.google.dev/pricing) for current rates
|
572 |
""")
|
573 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
574 |
# Footer
|
575 |
gr.HTML("""
|
576 |
<div style="text-align: center; margin-top: 20px; padding: 15px; background-color: #fff3cd; border-radius: 8px;">
|
|
|
589 |
return gr.File(value=filename, visible=True)
|
590 |
return gr.File(visible=False)
|
591 |
|
592 |
+
def test_api_connection(api_key_override):
|
593 |
+
# Use override if provided, otherwise use secrets
|
594 |
+
test_key = api_key_override if api_key_override.strip() else None
|
595 |
+
success, status = setup_gemini(test_key)
|
596 |
return status
|
597 |
|
598 |
+
# Test connection on startup if we have an API key
|
599 |
+
if initial_api_key:
|
600 |
+
def initial_connection_test():
|
601 |
+
return test_api_connection("")
|
602 |
+
|
603 |
+
interface.load(
|
604 |
+
fn=initial_connection_test,
|
605 |
+
outputs=[status_display]
|
606 |
+
)
|
607 |
+
|
608 |
# API key testing
|
609 |
api_key_input.change(
|
610 |
fn=test_api_connection,
|
|
|
630 |
|
631 |
if __name__ == "__main__":
|
632 |
print("π₯ Initializing Gemini Medical AI Analyzer...")
|
633 |
+
print("π Checking for API keys in secrets/environment...")
|
634 |
+
|
635 |
+
# Check for API key
|
636 |
+
api_key_found = get_api_key_from_secrets()
|
637 |
+
if api_key_found:
|
638 |
+
print("β
API key found in environment/secrets")
|
639 |
+
else:
|
640 |
+
print("β οΈ No API key found - user will need to provide one")
|
641 |
+
|
642 |
print("π No local model loading required - using Google Gemini Vision Pro API")
|
643 |
|
644 |
# Create and launch interface
|