|
import base64 |
|
import requests |
|
from io import BytesIO |
|
from PIL import Image |
|
import gradio as gr |
|
|
|
def encode_image(img): |
|
""" |
|
Encodes a PIL Image to a base64 string in PNG format. |
|
""" |
|
buffered = BytesIO() |
|
img.save(buffered, format="PNG") |
|
encoded_string = base64.b64encode(buffered.getvalue()).decode("utf-8") |
|
return f"data:image/png;base64,{encoded_string}" |
|
|
|
def get_api_response(api_key, user_inputs): |
|
""" |
|
Sends the user message and image to the Hyperbolic API and retrieves the response. |
|
""" |
|
if not api_key: |
|
return {"error": "API key is required."} |
|
|
|
if not user_inputs.get("text") and not user_inputs.get("image"): |
|
return {"error": "Please provide a text message, an image, or both."} |
|
|
|
try: |
|
headers = { |
|
"Content-Type": "application/json", |
|
"Authorization": f"Bearer {api_key}", |
|
} |
|
|
|
messages = [] |
|
|
|
if user_inputs.get("text"): |
|
messages.append({ |
|
"type": "text", |
|
"text": user_inputs["text"] |
|
}) |
|
|
|
if user_inputs.get("image"): |
|
|
|
base64_img = encode_image(user_inputs["image"]) |
|
messages.append({ |
|
"type": "image_url", |
|
"image_url": {"url": base64_img} |
|
}) |
|
|
|
payload = { |
|
"messages": [ |
|
{ |
|
"role": "user", |
|
"content": messages, |
|
} |
|
], |
|
"model": "Qwen/Qwen2-VL-72B-Instruct", |
|
"max_tokens": 2048, |
|
"temperature": 0.7, |
|
"top_p": 0.9, |
|
} |
|
|
|
api_endpoint = "https://api.hyperbolic.xyz/v1/chat/completions" |
|
response = requests.post(api_endpoint, headers=headers, json=payload) |
|
|
|
|
|
if response.status_code == 200: |
|
api_response = response.json() |
|
|
|
ai_reply = api_response.get("choices", [{}])[0].get("message", {}).get("content", "No response content.") |
|
return {"response": ai_reply} |
|
else: |
|
return {"error": f"API Error: {response.status_code} - {response.text}"} |
|
|
|
except Exception as e: |
|
return {"error": str(e)} |
|
|
|
def chatbot_response(api_key, user_inputs, history): |
|
""" |
|
Handles the chatbot interaction by updating the conversation history. |
|
""" |
|
user_text = user_inputs.get("text") |
|
user_image = user_inputs.get("image") |
|
|
|
|
|
user_content = [] |
|
if user_text: |
|
user_content.append(user_text) |
|
if user_image: |
|
|
|
img_data = encode_image(user_image) |
|
user_content.append(img_data) |
|
|
|
|
|
if user_content: |
|
history.append((user_content, None)) |
|
|
|
|
|
api_result = get_api_response(api_key, user_inputs) |
|
|
|
if "error" in api_result: |
|
ai_message = f"Error: {api_result['error']}" |
|
bot_content = [ai_message] |
|
else: |
|
ai_message = api_result["response"] |
|
bot_content = [ai_message] |
|
|
|
|
|
history[-1] = (history[-1][0], bot_content) |
|
|
|
return history, history |
|
|
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown( |
|
""" |
|
# 🖼️ Qwen2-VL-72B-Instruct with Hyperbolic API |
|
|
|
Engage in a conversation with the AI by sending text messages and/or uploading images. Enter your Hyperbolic API key to get started. |
|
""" |
|
) |
|
|
|
with gr.Row(): |
|
api_key_input = gr.Textbox( |
|
label="🔑 Hyperbolic API Key", |
|
type="password", |
|
placeholder="Enter your API key here", |
|
interactive=True |
|
) |
|
|
|
chatbot = gr.Chatbot(label="💬 Chatbot") |
|
|
|
with gr.Row(): |
|
chat_input = gr.MultimodalTextbox( |
|
label="Your Input", |
|
placeholder="Type your message and/or upload an image...", |
|
file_count="multiple", |
|
interactive=True |
|
) |
|
|
|
send_button = gr.Button("📤 Send") |
|
|
|
|
|
state = gr.State([]) |
|
|
|
send_button.click( |
|
fn=chatbot_response, |
|
inputs=[api_key_input, chat_input, state], |
|
outputs=[chatbot, state] |
|
) |
|
|
|
gr.Markdown( |
|
""" |
|
--- |
|
**Note:** Your API key is used only for this session and is not stored. Ensure you trust the environment in which you're running this application. |
|
""" |
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
demo.launch() |