Update app.py
Browse files
app.py
CHANGED
@@ -1,9 +1,7 @@
|
|
1 |
import gradio as gr
|
2 |
-
import requests
|
3 |
-
import os
|
4 |
-
import base64
|
5 |
from PIL import Image
|
6 |
import io
|
|
|
7 |
|
8 |
# Функция для кодирования изображения в base64
|
9 |
def encode_image_to_base64(image):
|
@@ -12,144 +10,79 @@ def encode_image_to_base64(image):
|
|
12 |
img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
|
13 |
return img_str
|
14 |
|
15 |
-
#
|
16 |
-
def
|
17 |
-
|
18 |
-
#
|
19 |
-
|
20 |
-
if image
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
# Создаем данные для запроса с закодированным изображением
|
25 |
-
payload = {
|
26 |
-
"model": "gpt-4-vision-preview",
|
27 |
-
"messages": [
|
28 |
-
{
|
29 |
-
"role": "user",
|
30 |
-
"content": [
|
31 |
-
{
|
32 |
-
"type": "text",
|
33 |
-
"text": start,
|
34 |
-
},
|
35 |
-
{
|
36 |
-
"type": "text",
|
37 |
-
"text": instruction,
|
38 |
-
},
|
39 |
-
{
|
40 |
-
"type": "image_url",
|
41 |
-
"image_url": {
|
42 |
-
"url": f"data:image/jpeg;base64,{base64_image}",
|
43 |
-
"detail": "high",
|
44 |
-
},
|
45 |
-
},
|
46 |
-
],
|
47 |
-
}
|
48 |
-
],
|
49 |
-
"max_tokens": 4095,
|
50 |
-
}
|
51 |
-
else:
|
52 |
-
# Создаем данные для запроса без изображения
|
53 |
-
payload = {
|
54 |
-
"model": "gpt-4-vision-preview",
|
55 |
-
"messages": [
|
56 |
-
{
|
57 |
-
"role": "user",
|
58 |
-
"content": start,
|
59 |
-
},
|
60 |
-
{
|
61 |
-
"role": "user",
|
62 |
-
"content": instruction,
|
63 |
-
}
|
64 |
-
],
|
65 |
-
"max_tokens": 4095,
|
66 |
-
}
|
67 |
-
|
68 |
-
# API ключ для OpenAI
|
69 |
-
api_key = os.getenv("OPENAI_API_KEY")
|
70 |
-
|
71 |
-
# Заголовки для запроса
|
72 |
-
headers = {
|
73 |
-
'Authorization': f'Bearer {api_key}',
|
74 |
-
'Content-Type': 'application/json',
|
75 |
-
}
|
76 |
-
|
77 |
-
# URL для запроса к API OpenAI
|
78 |
-
url = "https://api.openai.com/v1/chat/completions"
|
79 |
|
80 |
-
# Отправляем запрос в OpenAI
|
81 |
-
response = requests.post(url, headers=headers, json=payload)
|
82 |
-
|
83 |
-
# Проверяем ответ и возвращаем результат
|
84 |
-
if response.status_code == 200:
|
85 |
-
response_json = response.json()
|
86 |
-
try:
|
87 |
-
# Пытаемся извлечь текст из ответа
|
88 |
-
return response_json["choices"][0]["message"]["content"]
|
89 |
-
except Exception as e:
|
90 |
-
# Если есть ошибка в структуре JSON, выводим ее
|
91 |
-
return f"Error processing the image response: {e}"
|
92 |
-
else:
|
93 |
-
# Если произошла ошибка, возвращаем сообщение об ошибке
|
94 |
-
return f"Error: {response.status_code} - {response.text}"
|
95 |
-
|
96 |
-
# CSS стили для интерфейса
|
97 |
css = """
|
98 |
footer {visibility: hidden !important;}
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
.chat-container {height: calc(100vh - 70px); overflow-y: auto;}
|
104 |
-
.message {margin: 10px; padding: 10px; border-radius: 10px; background-color: #f0f0f0;}
|
105 |
-
.message.ai {background-color: #d1e7dd;}
|
106 |
-
.message.user {background-color: #f8d7da;}
|
107 |
"""
|
108 |
|
109 |
-
# Создаем интерфейс
|
110 |
with gr.Blocks(css=css) as demo:
|
111 |
-
with gr.Row():
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
else:
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
with chat_container:
|
131 |
-
gr.Markdown(f"**Вы:** {message}", css_classes=["message", "user"])
|
132 |
-
gr.Markdown(f"**AI:** {ai_response}", css_classes=["message", "ai"])
|
133 |
-
# Очищаем поле ввода сообщения
|
134 |
-
message_input.update(value="")
|
135 |
-
# Если было загружено изображение, убираем его
|
136 |
-
if image is not None:
|
137 |
-
clear_image()
|
138 |
-
|
139 |
-
def upload_image(file):
|
140 |
-
if file is not None:
|
141 |
-
image_input.update(value=file, visible=True)
|
142 |
-
attachment_button.update(value="❌")
|
143 |
-
else:
|
144 |
-
image_input.update(value=None, visible=False)
|
145 |
-
attachment_button.update(value="📎")
|
146 |
|
|
|
147 |
def clear_image():
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
demo.launch()
|
|
|
1 |
import gradio as gr
|
|
|
|
|
|
|
2 |
from PIL import Image
|
3 |
import io
|
4 |
+
import base64
|
5 |
|
6 |
# Функция для кодирования изображения в base64
|
7 |
def encode_image_to_base64(image):
|
|
|
10 |
img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
|
11 |
return img_str
|
12 |
|
13 |
+
# Функция, которая будет вызываться при нажатии кнопки отправки
|
14 |
+
def send_message(message, image=None):
|
15 |
+
# Здесь будет логика отправки сообщения и получения ответа от бота
|
16 |
+
# Для примера просто возвращаем полученное сообщение и изображение
|
17 |
+
response = f"Вы сказали: {message}"
|
18 |
+
if image:
|
19 |
+
img_str = encode_image_to_base64(image)
|
20 |
+
return response, f"data:image/jpeg;base64,{img_str}"
|
21 |
+
return response, None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
css = """
|
24 |
footer {visibility: hidden !important;}
|
25 |
+
.chat-container {height: 90vh; display: flex; flex-direction: column;}
|
26 |
+
.chat-messages {flex: 1; overflow-y: auto; padding: 10px;}
|
27 |
+
.input-group {display: flex; align-items: center; padding: 10px;}
|
28 |
+
.image-preview {max-width: 200px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);}
|
|
|
|
|
|
|
|
|
29 |
"""
|
30 |
|
31 |
+
# Создаем интерфейс
|
32 |
with gr.Blocks(css=css) as demo:
|
33 |
+
with gr.Row().style(equal_height=False):
|
34 |
+
chat_history = gr.Markdown("Привет! Я Помогатор, готов помочь тебе с любыми вопросами!) 😊").style(
|
35 |
+
container=True,
|
36 |
+
scroll="auto",
|
37 |
+
height="auto",
|
38 |
+
max_height="400px"
|
39 |
+
)
|
40 |
+
with gr.Row().style(justify_content="center", padding="10px"):
|
41 |
+
with gr.Column(scale=12):
|
42 |
+
input_message = gr.Textbox(placeholder="Введите ваше сообщение здесь...", lines=2, interactive=True, max_lines=5)
|
43 |
+
with gr.Column(scale=1, min_width="50px"):
|
44 |
+
send_button = gr.Button("Отправить")
|
45 |
+
with gr.Column(scale=1, min_width="50px"):
|
46 |
+
attach_button = gr.File(label="", file_count="single", interactive=True)
|
47 |
+
attach_button.style(icon="paperclip", hide_label=True)
|
48 |
+
with gr.Column(scale=1, min_width="50px"):
|
49 |
+
clear_button = gr.Button(label="")
|
50 |
+
clear_button.style(icon="times", hide_label=True, visible=False)
|
51 |
+
|
52 |
+
# Функция для отображения предварительного просмотра изображения
|
53 |
+
def preview_image(file_info):
|
54 |
+
if file_info is not None:
|
55 |
+
clear_button.style(visible=True)
|
56 |
+
attach_button.style(visible=False)
|
57 |
+
image = Image.open(io.BytesIO(file_info["content"]))
|
58 |
+
img_str = encode_image_to_base64(image)
|
59 |
+
return f"data:image/jpeg;base64,{img_str}"
|
60 |
else:
|
61 |
+
clear_button.style(visible=False)
|
62 |
+
attach_button.style(visible=True)
|
63 |
+
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
|
65 |
+
# Функция для очистки загруженного изображения
|
66 |
def clear_image():
|
67 |
+
attach_button.reset()
|
68 |
+
clear_button.style(visible=False)
|
69 |
+
attach_button.style(visible=True)
|
70 |
+
return None
|
71 |
+
|
72 |
+
# Функция для обработки отправки сообщения
|
73 |
+
def handle_send(message, image=None):
|
74 |
+
response, img_str = send_message(message, image)
|
75 |
+
new_message = f"**Вы:** {message}\n\n" if message else ""
|
76 |
+
new_message += f"\n\n" if img_str else ""
|
77 |
+
new_message += f"**Помогатор:** {response}\n\n"
|
78 |
+
chat_history.update(new_message + chat_history.value)
|
79 |
+
input_message.reset()
|
80 |
+
clear_image()
|
81 |
+
|
82 |
+
# Привязываем функции к кнопкам и полям ввода
|
83 |
+
send_button.click(handle_send, inputs=[input_message, attach_button], outputs=[])
|
84 |
+
attach_button.change(preview_image, inputs=[attach_button], outputs=[chat_history])
|
85 |
+
clear_button.click(clear_image, inputs=[], outputs=[chat_history])
|
86 |
+
|
87 |
+
# Запускаем интерфейс
|
88 |
demo.launch()
|