Imagebot / app.py
Vamshiboss8055's picture
Upload 2 files
864de13 verified
import os
import json
from typing import Optional
from datetime import datetime
import google.generativeai as genai
import gradio as gr
import PIL.Image
import tempfile
import requests
import base64
import io
GEMINI_API_KEY = "AIzaSyBSHcHdbVcvo5IvKDAq2fY1xsWDDb2-JUI"
MODEL_NAME = "models/gemini-2.5-flash"
# Configure the API
genai.configure(api_key=GEMINI_API_KEY)
class GeminiChatBot:
"""Main chatbot class with context management and multiple modes"""
def __init__(self, model_name: str = MODEL_NAME):
self.model = genai.GenerativeModel(model_name)
self.conversation_history = []
self.chat_session = None
self.system_prompt = ""
def set_system_prompt(self, mode: str):
"""Set system prompt based on chatbot mode"""
prompts = {
"general": """You are a helpful, accurate, and friendly AI assistant.
Provide clear, concise, and informative responses.
Always be honest about limitations and uncertainty.""",
"technical": """You are an expert technical support assistant.
Provide detailed technical solutions, code examples, and best practices.
When unsure, ask clarifying questions. Always suggest verification steps.""",
"creative": """You are a creative writing assistant with strong storytelling abilities.
Help users with creative writing, brainstorming, and narrative development.
Provide engaging and imaginative content.""",
"educational": """You are an educational tutor. Explain concepts clearly,
break down complex topics, and provide examples.
Encourage learning and ask clarifying questions.""",
"medical": """You are a medical information assistant.
Provide accurate health information and general guidance.
Always recommend consulting healthcare professionals for serious concerns.
Do NOT provide emergency medical advice."""
}
self.system_prompt = prompts.get(mode, prompts["general"])
def chat(self, user_message: str, image: Optional[PIL.Image.Image] = None, mode: str = "general", temperature: float = 0.7) -> str:
"""Generate response using Gemini with context via Requests"""
try:
self.set_system_prompt(mode)
# Prepare Image Data if exists
image_data = None
if image:
# Convert PIL Image to base64
buffered = io.BytesIO()
image.save(buffered, format="JPEG")
image_data = base64.b64encode(buffered.getvalue()).decode("utf-8")
# Override prompt for "Universal Image Analyzer" style if image is present
# User requested "Universal Image Analyzer, 3 lines text as output"
# We append this instruction to the user message
user_message = f"{user_message}\n\nAct as a Universal Image Analyzer. Analyze this image and provide the output in exactly 3 lines of text."
# Build Payload contents
contents = []
# 1. Add History (optional, if we want to keep context)
# Adapting history to the API format is good practice.
# Simplified for now to just last few turns + current message
for i in range(0, len(self.conversation_history), 2):
if i+1 < len(self.conversation_history):
user_text = self.conversation_history[i].replace("User: ", "")
bot_text = self.conversation_history[i+1].replace("Bot: ", "")
contents.append({"role": "user", "parts": [{"text": user_text}]})
contents.append({"role": "model", "parts": [{"text": bot_text}]})
# 2. Add Current Message
current_parts = []
if image_data:
current_parts.append({"inline_data": {"mime_type": "image/jpeg", "data": image_data}})
# Add system prompt as text part or separate instruction
final_user_content = f"[SYSTEM: {self.system_prompt}]\n\n{user_message}"
current_parts.append({"text": final_user_content})
contents.append({
"role": "user",
"parts": current_parts
})
# API URL
url = (
"https://generativelanguage.googleapis.com/v1beta/models/"
"gemini-2.5-flash:generateContent?key=" + GEMINI_API_KEY
)
payload = {
"contents": contents,
"generationConfig": {
"temperature": temperature,
"maxOutputTokens": 4000
}
}
headers = {"Content-Type": "application/json"}
# API CALL
response = requests.post(url, json=payload, headers=headers, timeout=30)
response.raise_for_status()
response_json = response.json()
# Extract Text
if "candidates" not in response_json or not response_json["candidates"]:
return "Error: No candidates in API response"
candidate = response_json["candidates"][0]
if (
"content" in candidate
and "parts" in candidate["content"]
and len(candidate["content"]["parts"]) > 0
):
bot_response = candidate["content"]["parts"][0].get("text", "")
else:
return "Error: Unexpected API response format"
# Store in history
self.conversation_history.append(f"User: {user_message[:100]}...")
self.conversation_history.append(f"Bot: {bot_response[:100]}...")
return bot_response
except Exception as e:
return f"Error: {str(e)}\n\nMake sure your API key is valid."
# Initialize chatbot
chatbot = GeminiChatBot()
# Gradio Interface Functions
def respond(message: str, image: Optional[PIL.Image.Image], chat_history: list, mode: str, temperature: float):
"""Respond to user message and return updated chat history"""
response = chatbot.chat(message, image=image, mode=mode, temperature=temperature)
content = ""
if image:
# Save image to temp file for display
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:
image.save(f.name)
img_path = f.name.replace("\\", "/")
content += f"![]({img_path})\n"
if message:
content += message
if content:
chat_history.append({"role": "user", "content": content})
chat_history.append({"role": "assistant", "content": response})
return "", None, chat_history
def clear_history():
"""Clear conversation history"""
chatbot.conversation_history = []
return [], ""
def export_chat(chat_history: list) -> str:
"""Export chat as JSON"""
if not chat_history:
return "No chat history to export"
export_data = {
"timestamp": datetime.now().isoformat(),
"conversation": chat_history
}
return json.dumps(export_data, indent=2)
# Create Gradio Interface
with gr.Blocks(title="Gemini ChatBot", theme=gr.themes.Soft()) as demo:
gr.Markdown("""
# 🤖 Nexus Intelligent ChatBot
A generalized, accurate chatbot powered by Google's Gemini AI.
Select your mode and start chatting!
""")
with gr.Row():
with gr.Column(scale=3):
chatbot_ui = gr.Chatbot(
label="Chat History",
height=500,
show_label=True
)
with gr.Column(scale=1):
gr.Markdown("### ⚙️ Settings")
mode = gr.Radio(
choices=["general", "technical", "creative", "educational", "medical"],
value="general",
label="Chat Mode",
info="Select conversation style"
)
temperature = gr.Slider(
minimum=0,
maximum=2,
value=0.7,
step=0.1,
label="Temperature",
info="Higher = more creative, Lower = more focused"
)
with gr.Row():
with gr.Column(scale=4):
msg_input = gr.Textbox(
placeholder="Type your message here...",
label="Your Message",
lines=2
)
with gr.Column(scale=1, min_width=200):
img_input = gr.Image(
type="pil",
label="Upload Image",
sources=["upload", "clipboard"],
show_label=True,
interactive=True
)
with gr.Row():
send_btn = gr.Button("Send", variant="primary", scale=2)
clear_btn = gr.Button("Clear Chat", scale=1)
export_btn = gr.Button("Export Chat", scale=1)
export_output = gr.Textbox(
label="Exported Chat (JSON)",
interactive=False,
visible=False
)
# Event handlers
send_btn.click(
respond,
inputs=[msg_input, img_input, chatbot_ui, mode, temperature],
outputs=[msg_input, img_input, chatbot_ui]
)
msg_input.submit(
respond,
inputs=[msg_input, img_input, chatbot_ui, mode, temperature],
outputs=[msg_input, img_input, chatbot_ui]
)
clear_btn.click(
clear_history,
outputs=[chatbot_ui, msg_input]
).then(
lambda: None,
None,
img_input,
)
def toggle_export_visibility():
return gr.update(visible=True)
def get_and_show_export(chat_history):
return export_chat(chat_history), gr.update(visible=True)
export_btn.click(
get_and_show_export,
inputs=[chatbot_ui],
outputs=[export_output, export_output]
)
gr.Markdown("""
### 📝 Chat Modes:
- **General**: Friendly assistant for everyday questions
- **Technical**: Expert technical support and code help
- **Creative**: Storytelling and creative writing
- **Educational**: Learning and concept explanation
- **Medical**: Health information (consult professionals for serious concerns)
### 🔑 Setup:
1. Get your API key from [Google AI Studio](https://aistudio.google.com/app/apikey)
2. Set `GEMINI_API_KEY` in `.env` file or environment variables
3. Run the app and start chatting!
""")
if __name__ == "__main__":
demo.launch()