gemini-webui / app.py
sdafd's picture
Update app.py
6b963cc verified
import gradio as gr
import google.genai as genai
from google.genai import types
from PIL import Image
import os
import textract
# List of available models (including experimental and recent ones)
models = [
"gemini-2.5-flash-preview-04-17",
"gemini-2.5-pro-preview-03-25",
"gemini-2.0-flash",
"gemini-2.0-flash-lite",
"gemini-2.0-flash-thinking-exp-01-21",
"gemini-1.5-pro",
"gemini-2.0-flash-exp-image-generation"
]
# Model types for handling inputs
model_types = {
"gemini-2.5-flash-preview-04-17": "text",
"gemini-2.5-pro-preview-03-25": "text",
"gemini-2.0-flash": "text",
"gemini-2.0-flash-lite": "text",
"gemini-2.0-flash-thinking-exp-01-21": "text",
"gemini-1.5-pro": "text",
"gemini-2.0-flash-exp-image-generationn": "multimodal"
}
# Function to validate API key
def validate_api_key(api_key):
try:
client = genai.Client(api_key=api_key)
client.models.list() # Validate by attempting to list models
return True, "API Key is valid."
except Exception as e:
return False, f"Invalid API Key: {str(e)}"
# Function to process uploaded files
def process_files(files, model_type):
inputs = []
for file_path in files:
if model_type == "multimodal" and file_path.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp')):
img = Image.open(file_path)
inputs.append(img)
else:
try:
text = textract.process(file_path).decode('utf-8')
inputs.append(text)
except Exception as e:
inputs.append(f"Error extracting text from {os.path.basename(file_path)}: {str(e)}")
return inputs
# Chat submit function
def chat_submit_func(message, files, chat_history, model, temperature, top_p, max_tokens, api_key):
print(model)
client = genai.Client(api_key=api_key)
# Prepare inputs
if model_types[model] == "text" and files:
chat_history.append((message, "Warning: Files are not supported for text-only models. Converting to text where possible."))
processed_inputs = process_files(files, "text")
inputs = [message] + processed_inputs
else:
processed_inputs = process_files(files, model_types[model]) if files else []
inputs = [message] + processed_inputs
# Generation configuration
generation_config = {
"temperature": temperature,
"top_p": top_p,
"max_output_tokens": max_tokens,
}
try:
response = client.models.generate_content(inputs, model=model, config=generation_config)
response_text = ""
response_images = []
# Parse response
for candidate in response.candidates:
for part in candidate.content.parts:
if hasattr(part, 'text') and part.text:
response_text += part.text
elif hasattr(part, 'file_data') and part.file_data:
# Assuming file_data provides a URL; adjust if base64 or other format
image_url = part.file_data.url
response_images.append(image_url)
# Update chat history
user_message = message
if files:
user_message += "\nFiles: " + ", ".join([os.path.basename(f) for f in files])
chat_history.append((user_message, None))
bot_message = response_text
if response_images:
bot_message += "\n" + "\n".join([f"![image]({img})" for img in response_images])
chat_history.append((None, bot_message))
return chat_history, ""
except Exception as e:
chat_history.append((message, f"Error: {str(e)}"))
return chat_history, ""
# Single response submit function
def single_submit_func(prompt, files, model, temperature, top_p, max_tokens, api_key):
print(model)
client = genai.Client(api_key=api_key)
# Prepare inputs
if model_types[model] == "text" and files:
processed_inputs = process_files(files, "text")
inputs = [prompt] + processed_inputs
warning = "Warning: Files converted to text for text-only model."
else:
processed_inputs = process_files(files, model_types[model]) if files else []
inputs = [prompt] + processed_inputs
warning = ""
contents = [
types.Content(
role="user",
parts=[
types.Part.from_text(text=prompt),
],
),
]
generate_content_config = types.GenerateContentConfig(
response_mime_type="text/plain",
)
try:
response = client.models.generate_content(model=model, contents=contents, config=generate_content_config)
response_text = warning
response_images = []
# Parse response
for candidate in response.candidates:
for part in candidate.content.parts:
if hasattr(part, 'text') and part.text:
response_text += part.text
elif hasattr(part, 'file_data') and part.file_data:
image_url = part.file_data.url
response_images.append(image_url)
return response_text, response_images
except Exception as e:
return f"Error: {str(e)}", []
# Gradio interface
with gr.Blocks(title="Gemini API Interface") as app:
# API Key Section
api_key_input = gr.Textbox(label="Gemini API Key", type="password", placeholder="Enter your Gemini API Key")
validate_btn = gr.Button("Validate API Key")
key_status = gr.Textbox(label="API Key Status", interactive=False)
key_validated = gr.State(False)
# Model and Parameters Section (hidden until key is validated)
with gr.Group(visible=False) as config_group:
model_selector = gr.Dropdown(choices=models, label="Select Model", value=models[0])
temperature = gr.Slider(0, 1, value=0.7, label="Temperature", step=0.01)
top_p = gr.Slider(0, 1, value=0.9, label="Top P", step=0.01)
max_tokens = gr.Number(value=512, label="Max Tokens", minimum=1)
# Tabs for Chat and Single Response (hidden until key is validated)
with gr.Tabs(visible=False) as tabs:
with gr.TabItem("Chat"):
chat_display = gr.Chatbot(label="Chat History")
chat_input = gr.Textbox(label="Your Message", placeholder="Type your message here...")
chat_files = gr.File(label="Upload Files", file_count="multiple")
chat_submit_btn = gr.Button("Send")
chat_status = gr.Textbox(label="Status", interactive=False)
with gr.TabItem("Single Response"):
single_input = gr.Textbox(label="Prompt", placeholder="Enter your prompt here...")
single_files = gr.File(label="Upload Files", file_count="multiple")
single_submit_btn = gr.Button("Generate")
single_text_output = gr.Textbox(label="Response Text", interactive=False)
single_image_output = gr.Gallery(label="Response Images")
# Validation logic
def on_validate_key(api_key):
is_valid, status = validate_api_key(api_key)
if is_valid:
return status, True, gr.update(visible=True), gr.update(visible=True)
return status, False, gr.update(visible=False), gr.update(visible=False)
validate_btn.click(
on_validate_key,
inputs=[api_key_input],
outputs=[key_status, key_validated, config_group, tabs]
)
# Chat submission
chat_submit_btn.click(
chat_submit_func,
inputs=[chat_input, chat_files, chat_display, model_selector, temperature, top_p, max_tokens, api_key_input],
outputs=[chat_display, chat_status]
)
# Single response submission
single_submit_btn.click(
single_submit_func,
inputs=[single_input, single_files, model_selector, temperature, top_p, max_tokens, api_key_input],
outputs=[single_text_output, single_image_output]
)
app.launch()