|
import gradio as gr |
|
import os |
|
import json |
|
import requests |
|
import xml.etree.ElementTree as ET |
|
from huggingface_hub import HfApi, create_repo |
|
|
|
|
|
LOG_FILE = '/persistent-storage/chat_logs.txt' |
|
persistent_dir = '/persistent-storage' |
|
|
|
if not os.path.exists(persistent_dir): |
|
try: |
|
os.makedirs(persistent_dir, exist_ok=True) |
|
print(f"Kalıcı depolama dizini oluşturuldu: {persistent_dir}") |
|
except Exception as e: |
|
print(f"Kalıcı depolama dizini oluşturulamadı: {e}. Geçici dizine geri dönülüyor.") |
|
LOG_FILE = 'chat_logs.txt' |
|
|
|
print(f"Dosya yolu: {os.path.abspath(LOG_FILE)}") |
|
|
|
|
|
API_URL = "https://api.openai.com/v1/chat/completions" |
|
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") |
|
if not OPENAI_API_KEY: |
|
print("Hata: OPENAI_API_KEY çevre değişkeni ayarlanmamış!") |
|
|
|
|
|
url = 'https://www.trekbisiklet.com.tr/output/8582384479' |
|
response = requests.get(url) |
|
root = ET.fromstring(response.content) |
|
|
|
products = [] |
|
for item in root.findall('item'): |
|
if item.find('isOptionOfAProduct').text == '1' and item.find('stockAmount').text > '0': |
|
name_words = item.find('rootlabel').text.lower().split() |
|
name = name_words[0] |
|
full_name = ' '.join(name_words) |
|
stockAmount = "stokta" |
|
price = item.find('priceWithTax').text |
|
item_info = (stockAmount, price) |
|
products.append((name, item_info, full_name)) |
|
|
|
|
|
hfapi = os.getenv("hfapi") |
|
if not hfapi: |
|
raise ValueError("hfapi ortam değişkeni ayarlanmamış!") |
|
|
|
|
|
create_repo("BF", token=hfapi, repo_type="space", space_sdk="gradio", exist_ok=True) |
|
|
|
def predict(system_msg, inputs, top_p, temperature, chat_counter, chatbot=None, history=None): |
|
if chatbot is None: |
|
chatbot = [] |
|
if history is None: |
|
history = [] |
|
|
|
headers = { |
|
"Content-Type": "application/json", |
|
"Authorization": f"Bearer {OPENAI_API_KEY}" |
|
} |
|
print(f"System message: {system_msg}") |
|
|
|
multi_turn_message = [ |
|
{"role": "system", "content": "Bir önceki sohbeti unut. Vereceğin ürün bilgisi, bu bilginin içinde yan yana yazmıyorsa veya arada başka bilgiler yazıyor ise, o bilgiyi vermeyeceksin çünkü o bilgi yanlıştır. ... (uzun metin)"} |
|
] |
|
|
|
messages = multi_turn_message.copy() |
|
input_words = [str(word).lower() for word in inputs.split()] |
|
for product_info in products: |
|
if product_info[0] in input_words: |
|
new_msg = f"{product_info[2]} {product_info[1][0]} ve fiyatı EURO {product_info[1][1]}" |
|
print(new_msg) |
|
messages.append({"role": "system", "content": new_msg}) |
|
|
|
for data in chatbot: |
|
messages.append({"role": data["role"], "content": data["content"]}) |
|
|
|
messages.append({"role": "user", "content": inputs}) |
|
|
|
payload = { |
|
"model": "gpt-4o", |
|
"messages": messages, |
|
"temperature": 0.7, |
|
"top_p": 0.9, |
|
"n": 1, |
|
"stream": True, |
|
"presence_penalty": 0, |
|
"frequency_penalty": 0, |
|
} |
|
|
|
chat_counter += 1 |
|
history.append(inputs) |
|
print(f"Logging: Payload is - {payload}") |
|
|
|
|
|
try: |
|
with open(LOG_FILE, 'a', encoding='utf-8') as f: |
|
f.write(f"User: {inputs}\n") |
|
print(f"Kullanıcı mesajı dosyaya yazıldı: {inputs}") |
|
except Exception as e: |
|
print(f"Dosya yazma hatası (Kullanıcı): {e}") |
|
|
|
|
|
chatbot.append({"role": "user", "content": inputs}) |
|
response = requests.post(API_URL, headers=headers, json=payload, stream=True) |
|
print(f"Logging: Response code - {response.status_code}") |
|
if response.status_code != 200: |
|
print(f"API hatası: {response.text}") |
|
return chatbot, history, chat_counter |
|
|
|
partial_words = "" |
|
counter = 0 |
|
for chunk in response.iter_lines(): |
|
counter += 1 |
|
if not chunk: |
|
continue |
|
chunk_str = chunk.decode('utf-8') |
|
print(f"Chunk {counter}: {chunk_str}") |
|
if chunk_str.startswith("data: ") and chunk_str != "data: [DONE]": |
|
try: |
|
chunk_data = json.loads(chunk_str[6:]) |
|
delta = chunk_data['choices'][0]['delta'] |
|
if 'content' in delta and delta['content']: |
|
content = delta['content'] |
|
partial_words += content |
|
print(f"İçerik eklendi: {content}") |
|
print(f"Güncel partial_words: {partial_words}") |
|
except json.JSONDecodeError as e: |
|
print(f"JSON parse hatası: {e} - Chunk: {chunk_str}") |
|
elif chunk_str == "data: [DONE]": |
|
print("Akış tamamlandı: [DONE] alındı") |
|
if partial_words: |
|
history.append(partial_words) |
|
chatbot.append({"role": "assistant", "content": partial_words}) |
|
try: |
|
with open(LOG_FILE, 'a', encoding='utf-8') as f: |
|
f.write(f"Bot: {partial_words}\n") |
|
print(f"Bot yanıtı dosyaya yazıldı: {partial_words}") |
|
except Exception as e: |
|
print(f"Dosya yazma hatası (Bot): {e}") |
|
chat = chatbot.copy() |
|
if partial_words and chat and chat[-1]["role"] == "user": |
|
chat.append({"role": "assistant", "content": partial_words}) |
|
elif partial_words and chat and chat[-1]["role"] == "assistant": |
|
chat[-1] = {"role": "assistant", "content": partial_words} |
|
yield chat, history, chat_counter |
|
print(f"Son chatbot durumu: {chatbot}") |
|
return chatbot, history, chat_counter |
|
|
|
def save_chat(chatbot): |
|
file_path = os.path.abspath(LOG_FILE) |
|
try: |
|
with open(LOG_FILE, 'a', encoding='utf-8') as f: |
|
f.write("\n--- Kayıt Edilen Sohbet ---\n") |
|
for msg in chatbot: |
|
f.write(f"{msg['role'].capitalize()}: {msg['content']}\n") |
|
print(f"Sohbet dosyaya kaydedildi: {file_path}") |
|
return f"Sohbet başarıyla kaydedildi!\nDosya: {file_path}" |
|
except Exception as e: |
|
print(f"Kayıt hatası: {e}") |
|
return f"Kayıt hatası: {e}\nDosya: {file_path}" |
|
|
|
def reset_textbox(): |
|
return gr.update(value='') |
|
|
|
def upload_logs_to_hf(repo_id: str, hf_token: str, local_log_file: str = "chat_logs.txt"): |
|
""" |
|
Log dosyasını Hugging Face Hub repository'sine yükler. |
|
|
|
Args: |
|
repo_id (str): Repository kimliği (örn. "SamiKoen/BF"). |
|
hf_token (str): Hugging Face API token'ınız. |
|
local_log_file (str): Yüklenecek log dosyasının yolu. |
|
""" |
|
api = HfApi(token=hf_token) |
|
try: |
|
api.upload_file( |
|
path_or_fileobj=local_log_file, |
|
path_in_repo=local_log_file, |
|
repo_id=repo_id, |
|
repo_type="space", |
|
commit_message="Log dosyası güncellendi" |
|
) |
|
print(f"Log dosyası başarıyla yüklendi: {local_log_file}") |
|
except Exception as e: |
|
print(f"Log dosyası yüklenirken hata oluştu: {e}") |
|
|
|
def save_chat_and_upload(chatbot): |
|
save_status = save_chat(chatbot) |
|
HF_REPO_ID = "SamiKoen/BF" |
|
hfapi = os.getenv("hfapi") |
|
upload_logs_to_hf(HF_REPO_ID, hfapi) |
|
return save_status |
|
|
|
|
|
demo_css = """ |
|
#send_button, #save_button { |
|
background-color: #0b93f6; |
|
border: none; |
|
color: white; |
|
font-size: 16px; |
|
border-radius: 10%; |
|
width: 100px !important; |
|
height: 37px !important; |
|
display: inline-flex; |
|
align-items: center; |
|
justify-content: center; |
|
cursor: pointer; |
|
transition: background-color 0.3s; |
|
margin: 5px; |
|
} |
|
#send_button:hover, #save_button:hover { |
|
background-color: #0077c0; |
|
} |
|
.fixed_button_container { |
|
padding: 0px; |
|
margin: 0px 0 0 0px; |
|
} |
|
#custom_row { |
|
width: 150% !important; |
|
flex-wrap: nowrap !important; |
|
} |
|
@media only screen and (max-width: 1000px) { |
|
.custom_row { |
|
flex-wrap: nowrap !important; |
|
} |
|
} |
|
#chatbot { |
|
height: 100vh; |
|
overflow-y: auto; |
|
} |
|
""" |
|
|
|
theme = gr.themes.Base( |
|
neutral_hue="blue", |
|
text_size="sm", |
|
spacing_size="sm", |
|
) |
|
|
|
with gr.Blocks(css=demo_css, theme=theme) as demo: |
|
if not os.path.exists(LOG_FILE): |
|
with open(LOG_FILE, 'w', encoding='utf-8') as f: |
|
f.write("--- Yeni Sohbet ---\n") |
|
|
|
with gr.Column(elem_id="col_container"): |
|
with gr.Accordion("", open=False, visible=False): |
|
system_msg = gr.Textbox(value="") |
|
new_msg = gr.Textbox(value="") |
|
accordion_msg = gr.HTML(value="", visible=False) |
|
|
|
chatbot = gr.Chatbot(label='Trek Asistanı', elem_id="chatbot", type="messages") |
|
|
|
with gr.Row(elem_id="custom_row"): |
|
inputs = gr.Textbox( |
|
placeholder="Buraya yazın", |
|
show_label=False, |
|
container=False, |
|
) |
|
with gr.Column(elem_classes="fixed_button_container"): |
|
send_button = gr.Button(value="Gönder", elem_id="send_button") |
|
save_button = gr.Button(value="Kayıt Et", elem_id="save_button") |
|
|
|
state = gr.State([]) |
|
save_status = gr.Textbox(label="Kayıt Durum", interactive=False) |
|
|
|
with gr.Accordion("", open=False, visible=False): |
|
top_p = gr.Slider(minimum=0, maximum=1.0, value=0.5, step=0.05, interactive=False, visible=False) |
|
temperature = gr.Slider(minimum=0, maximum=5.0, value=0.1, step=0.1, interactive=False, visible=False) |
|
chat_counter = gr.Number(value=0, visible=False, precision=0) |
|
|
|
inputs.submit(predict, [system_msg, inputs, top_p, temperature, chat_counter, chatbot, state], [chatbot, state, chat_counter]) |
|
inputs.submit(reset_textbox, [], [inputs]) |
|
send_button.click(predict, [system_msg, inputs, top_p, temperature, chat_counter, chatbot, state], [chatbot, state, chat_counter]) |
|
send_button.click(reset_textbox, [], [inputs]) |
|
save_button.click(save_chat_and_upload, [chatbot], [save_status]) |
|
|
|
demo.queue(max_size=10).launch(debug=True) |