Spaces:
Running
Running
# modules/gemini_handler.py | |
""" | |
Dedicated module for all interactions with the Google Gemini API. | |
It initializes and configures the models, and provides clean, async functions | |
for both text and multi-modal (vision) generation, including robust error handling. | |
""" | |
import google.generativeai as genai | |
from PIL import Image | |
# ============================================================================== | |
# CORRECTED LINE: The import path now correctly points to api_clients/config.py | |
from api_clients.config import GEMINI_API_KEY | |
# ============================================================================== | |
# --- Configuration --- | |
if not GEMINI_API_KEY: | |
raise ValueError("FATAL: GEMINI_API_KEY not found. Please set it in your environment/secrets.") | |
genai.configure(api_key=GEMINI_API_KEY) | |
# Configuration for predictable, factual responses | |
generation_config = { | |
"temperature": 0.1, | |
"top_p": 0.95, | |
"top_k": 40, | |
"max_output_tokens": 8192, # Increased for detailed reports | |
} | |
# Safety settings are relaxed slightly for medical context, but still block high-risk content. | |
# This prevents the model from refusing to discuss health topics. | |
safety_settings = [ | |
{"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_MEDIUM_AND_ABOVE"}, | |
{"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_MEDIUM_AND_ABOVE"}, | |
{"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "BLOCK_ONLY_HIGH"}, | |
{"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_MEDIUM_AND_ABOVE"}, | |
] | |
# --- Model Initialization --- | |
try: | |
# Model for text-based tasks (synthesis, extraction) | |
text_model = genai.GenerativeModel( | |
model_name="gemini-1.5-flash-latest", # Use a fast and capable model | |
generation_config=generation_config, | |
safety_settings=safety_settings | |
) | |
# Model for multi-modal tasks (analyzing medical images) | |
vision_model = genai.GenerativeModel( | |
model_name="gemini-1.5-flash-latest", # Vision models are also great at text | |
generation_config=generation_config, | |
safety_settings=safety_settings | |
) | |
except Exception as e: | |
raise RuntimeError(f"Failed to initialize Gemini models: {e}") | |
async def generate_text_response(prompt: str) -> str: | |
""" | |
Calls the Gemini text model with a given prompt. | |
Args: | |
prompt (str): The detailed prompt for the AI. | |
Returns: | |
str: The AI's generated text response, or an error message. | |
""" | |
try: | |
response = await text_model.generate_content_async(prompt) | |
if not response.parts: | |
return "Error: The AI response was blocked, possibly due to safety filters or lack of content. Please rephrase." | |
return response.text | |
except Exception as e: | |
print(f"Gemini API Error (Text): {e}") | |
return f"An error occurred while communicating with the AI model. Details: {e}" | |
async def analyze_image_with_text(prompt: str, image: Image.Image) -> str: | |
""" | |
Calls the Gemini vision model with a text prompt and an image. | |
Args: | |
prompt (str): The text prompt to guide the image analysis. | |
image (Image.Image): The PIL image to be analyzed. | |
Returns: | |
str: The AI's generated text analysis, or an error message. | |
""" | |
try: | |
response = await vision_model.generate_content_async([prompt, image]) | |
if not response.parts: | |
return "Error: The AI response for the image was blocked. The image may violate safety policies." | |
return response.text | |
except Exception as e: | |
print(f"Gemini API Error (Vision): {e}") | |
return f"An error occurred while analyzing the image with the AI. Details: {e}" |