feat: dynamic multi-alias API key resolution and restart trigger
Browse files- backend/main.py +2 -2
- backend/pipeline.py +30 -3
backend/main.py
CHANGED
|
@@ -126,7 +126,7 @@ async def health_check():
|
|
| 126 |
"environment": settings.app_env,
|
| 127 |
"ai_engine": "Google Gemini 3.8 Flash Vision Engine",
|
| 128 |
"engine_type": "Resilient Multimodal Vision Platform (Cascading 3.8 -> 3.5 -> 2.5)",
|
| 129 |
-
"gemini_active":
|
| 130 |
"ai_active": inference_engine.is_configured(),
|
| 131 |
"device": inference_engine.device,
|
| 132 |
"knowledge_base_entries": len(DISEASE_KNOWLEDGE_BASE)
|
|
@@ -159,7 +159,7 @@ async def api_status():
|
|
| 159 |
"status": "online",
|
| 160 |
"version": settings.app_version,
|
| 161 |
"environment": settings.app_env,
|
| 162 |
-
"gemini_active":
|
| 163 |
"ai_model": "Google Gemini 3.8 Flash",
|
| 164 |
"ai_active": inference_engine.is_configured(),
|
| 165 |
"supported_crops_count": "Universal"
|
|
|
|
| 126 |
"environment": settings.app_env,
|
| 127 |
"ai_engine": "Google Gemini 3.8 Flash Vision Engine",
|
| 128 |
"engine_type": "Resilient Multimodal Vision Platform (Cascading 3.8 -> 3.5 -> 2.5)",
|
| 129 |
+
"gemini_active": inference_engine.is_configured(),
|
| 130 |
"ai_active": inference_engine.is_configured(),
|
| 131 |
"device": inference_engine.device,
|
| 132 |
"knowledge_base_entries": len(DISEASE_KNOWLEDGE_BASE)
|
|
|
|
| 159 |
"status": "online",
|
| 160 |
"version": settings.app_version,
|
| 161 |
"environment": settings.app_env,
|
| 162 |
+
"gemini_active": inference_engine.is_configured(),
|
| 163 |
"ai_model": "Google Gemini 3.8 Flash",
|
| 164 |
"ai_active": inference_engine.is_configured(),
|
| 165 |
"supported_crops_count": "Universal"
|
backend/pipeline.py
CHANGED
|
@@ -162,16 +162,43 @@ class PureGeminiInferenceEngine:
|
|
| 162 |
"""
|
| 163 |
|
| 164 |
def __init__(self):
|
| 165 |
-
self.api_key = settings.gemini_api_key or os.getenv("GEMINI_API_KEY")
|
| 166 |
self.model_name = "Google Gemini 3.8 Flash Resilient Multimodal Vision"
|
| 167 |
self.model_type = "Multi-Model Resilient Multimodal Vision"
|
| 168 |
self.device = "cloud (Google AI TPU/GPU)"
|
| 169 |
-
self.is_loaded = bool(self.api_key and len(self.api_key.strip()) > 10)
|
| 170 |
# In-memory cache: hash -> (timestamp, DiagnosisResponse)
|
| 171 |
self._cache: Dict[str, Tuple[float, DiagnosisResponse]] = {}
|
| 172 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
def is_configured(self) -> bool:
|
| 174 |
-
return
|
| 175 |
|
| 176 |
async def predict_from_image_bytes_async(self, image_bytes: bytes) -> DiagnosisResponse:
|
| 177 |
"""
|
|
|
|
| 162 |
"""
|
| 163 |
|
| 164 |
def __init__(self):
|
|
|
|
| 165 |
self.model_name = "Google Gemini 3.8 Flash Resilient Multimodal Vision"
|
| 166 |
self.model_type = "Multi-Model Resilient Multimodal Vision"
|
| 167 |
self.device = "cloud (Google AI TPU/GPU)"
|
|
|
|
| 168 |
# In-memory cache: hash -> (timestamp, DiagnosisResponse)
|
| 169 |
self._cache: Dict[str, Tuple[float, DiagnosisResponse]] = {}
|
| 170 |
|
| 171 |
+
@property
|
| 172 |
+
def api_key(self) -> Optional[str]:
|
| 173 |
+
for var_name in [
|
| 174 |
+
"GEMINI_API_KEY",
|
| 175 |
+
"GOOGLE_API_KEY",
|
| 176 |
+
"GEMINI_KEY",
|
| 177 |
+
"gemini_api_key",
|
| 178 |
+
"google_api_key",
|
| 179 |
+
"gemini_key",
|
| 180 |
+
"API_KEY"
|
| 181 |
+
]:
|
| 182 |
+
val = os.getenv(var_name)
|
| 183 |
+
if val:
|
| 184 |
+
cleaned = val.strip().strip('"').strip("'").strip()
|
| 185 |
+
if len(cleaned) > 10:
|
| 186 |
+
return cleaned
|
| 187 |
+
|
| 188 |
+
cfg_key = getattr(settings, "gemini_api_key", None)
|
| 189 |
+
if cfg_key:
|
| 190 |
+
cleaned = cfg_key.strip().strip('"').strip("'").strip()
|
| 191 |
+
if len(cleaned) > 10:
|
| 192 |
+
return cleaned
|
| 193 |
+
|
| 194 |
+
return None
|
| 195 |
+
|
| 196 |
+
@property
|
| 197 |
+
def is_loaded(self) -> bool:
|
| 198 |
+
return self.is_configured()
|
| 199 |
+
|
| 200 |
def is_configured(self) -> bool:
|
| 201 |
+
return self.api_key is not None
|
| 202 |
|
| 203 |
async def predict_from_image_bytes_async(self, image_bytes: bytes) -> DiagnosisResponse:
|
| 204 |
"""
|