|
import gradio as gr |
|
import requests |
|
import os |
|
import base64 |
|
from PIL import Image |
|
import io |
|
|
|
|
|
def encode_image_to_base64(image): |
|
buffered = io.BytesIO() |
|
image.save(buffered, format="JPEG") |
|
img_str = base64.b64encode(buffered.getvalue()).decode("utf-8") |
|
return img_str |
|
|
|
|
|
def ask_openai_with_image(instruction, image, low): |
|
start = "..." |
|
|
|
|
|
if image is not None: |
|
|
|
base64_image = encode_image_to_base64(image) |
|
|
|
|
|
payload = { |
|
"model": "gpt-4-vision-preview", |
|
"messages": [ |
|
{ |
|
"role": "user", |
|
"content": [ |
|
{ |
|
"type": "text", |
|
"text": start, |
|
}, |
|
{ |
|
"type": "text", |
|
"text": instruction, |
|
}, |
|
{ |
|
"type": "image_url", |
|
"image_url": { |
|
"url": f"data:image/jpeg;base64,{base64_image}", |
|
"detail": "high", |
|
}, |
|
}, |
|
], |
|
} |
|
], |
|
"max_tokens": 4095, |
|
} |
|
else: |
|
|
|
payload = { |
|
"model": "gpt-4-vision-preview", |
|
"messages": [ |
|
{ |
|
"role": "user", |
|
"content": start, |
|
}, |
|
{ |
|
"role": "user", |
|
"content": instruction, |
|
} |
|
], |
|
"max_tokens": 4095, |
|
} |
|
|
|
|
|
api_key = os.getenv("OPENAI_API_KEY") |
|
|
|
|
|
headers = { |
|
'Authorization': f'Bearer {api_key}', |
|
'Content-Type': 'application/json', |
|
} |
|
|
|
|
|
url = "https://api.openai.com/v1/chat/completions" |
|
|
|
|
|
response = requests.post(url, headers=headers, json=payload) |
|
|
|
|
|
if response.status_code == 200: |
|
response_json = response.json() |
|
try: |
|
|
|
return response_json["choices"][0]["message"]["content"] |
|
except Exception as e: |
|
|
|
return f"Error processing the image response: {e}" |
|
else: |
|
|
|
return f"Error: {response.status_code} - {response.text}" |
|
|
|
|
|
css = """ |
|
footer {visibility: hidden !important;} |
|
#message-input {width: calc(100% - 75px);} |
|
#image-preview {border-radius: 10px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); max-width: 100px; max-height: 100px;} |
|
#send-button {margin-left: 10px;} |
|
#attachment-button {margin-right: 10px;} |
|
.chat-container {height: calc(100vh - 70px); overflow-y: auto;} |
|
.message {margin: 10px; padding: 10px; border-radius: 10px; background-color: #f0f0f0;} |
|
.message.ai {background-color: #d1e7dd;} |
|
.message.user {background-color: #f8d7da;} |
|
""" |
|
|
|
|
|
with gr.Blocks(css=css) as demo: |
|
with gr.Row(): |
|
chat_container = gr.Column(variant="panel", scroll="auto", id="chat-container", elem_id="chat-container") |
|
with chat_container: |
|
gr.Markdown("Привет! Я Помогатор, готов помочь тебе с любыми вопросами!) 😊", css_classes=["message", "ai"]) |
|
|
|
with gr.Row(): |
|
attachment_button = gr.Button(value="📎", id="attachment-button") |
|
message_input = gr.Textbox(placeholder="Напишите сообщение...", id="message-input") |
|
send_button = gr.Button(value="➤", id="send-button") |
|
image_input = gr.Image(type="pil", interactive=False, visible=False, id="image-preview") |
|
|
|
def send_message(message, image): |
|
if image is not None: |
|
image_base64 = encode_image_to_base64(image) |
|
ai_response = ask_openai_with_image(message, image, low=False) |
|
else: |
|
ai_response = ask_openai_with_image(message, None, low=False) |
|
|
|
|
|
with chat_container: |
|
gr.Markdown(f"**Вы:** {message}", css_classes=["message", "user"]) |
|
gr.Markdown(f"**AI:** {ai_response}", css_classes=["message", "ai"]) |
|
|
|
message_input.update(value="") |
|
|
|
if image is not None: |
|
clear_image() |
|
|
|
def upload_image(file): |
|
if file is not None: |
|
image_input.update(value=file, visible=True) |
|
attachment_button.update(value="❌") |
|
else: |
|
image_input.update(value=None, visible=False) |
|
attachment_button.update(value="📎") |
|
|
|
def clear_image(): |
|
image_input.update(value=None, visible=False) |
|
attachment_button.update(value="📎") |
|
|
|
message_input.change(send_message, [message_input, image_input], chat_container) |
|
send_button.click(send_message, [message_input, image_input], chat_container) |
|
attachment_button.click(clear_image if attachment_button.value == "❌" else upload_image, image_input, image_input) |
|
|
|
demo.launch() |