SamiKoen commited on
Commit
6a4857c
·
verified ·
1 Parent(s): 31d8727

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -245
app.py CHANGED
@@ -1,256 +1,46 @@
1
- import os
2
- import openai
3
  import gradio as gr
4
- import xml.etree.ElementTree as ET
5
- import pandas as pd # Excel okuma için pandas
6
- import docx # Word (.docx) dosyalarını okuma
7
- import threading
8
- import time
9
-
10
- # OpenAI API anahtarını ortam değişkeninden al
11
- openai.api_key = os.getenv("OPENAI_API_KEY")
12
-
13
- # OpenAI modeli ayarları
14
- OPENAI_CHAT_MODEL = "gpt-4" # Metin tabanlı GPT modeli
15
- TTS_MODEL = "tts-1" # OpenAI TTS modeli
16
- TTS_VOICE = "nova" # Tercih edilen ses
17
 
18
- # Trek ürün bilgileri XML dosyasını yükle (stok ve fiyat kontrolü için)
19
- try:
20
- trek_tree = ET.parse("trek_products.xml")
21
- trek_root = trek_tree.getroot()
22
- except Exception as e:
23
- trek_root = None
24
- print(f"XML yüklenirken hata oluştu: {e}")
25
 
26
- # Sistem mesajı ve özel kurallar (sohbetin her başında yer alacak temel yönergeler)
27
- SYSTEM_PROMPT = (
28
- "You are Trek Chatbot, an AI assistant that provides information about Trek products and performs various tasks. "
29
- "Follow the given rules and guidelines. If the user asks for Trek product info, provide stock and price from the XML database. "
30
- "If the user requests to read a file, fetch its content from Google Drive. "
31
- "Always respond helpfully in the same language as the user's question, and keep a friendly tone."
32
- )
33
 
34
- def check_trek_product_info(product_id):
35
- """
36
- Verilen ürün kodu/ID için Trek XML veritabanından fiyat ve stok bilgisini döndürür.
37
- Bulunamazsa (None, None) döndürür.
38
- """
39
- price = None
40
- stock = None
41
- if trek_root is None:
42
- return price, stock
43
- # XML yapısında <product><id>...</id><price>...</price><stock>...</stock></product> şeklinde olduğunu varsayıyoruz
44
- for product in trek_root.findall("product"):
45
- pid = product.find("id").text if product.find("id") is not None else ""
46
- if pid and product_id.lower() == pid.lower():
47
- # Ürün eşleşti, fiyat ve stok bilgilerini al
48
- price_elem = product.find("price")
49
- stock_elem = product.find("stock")
50
- price = price_elem.text if price_elem is not None else None
51
- stock = stock_elem.text if stock_elem is not None else None
52
- break
53
- return price, stock
54
 
55
- def read_file_from_drive(file_path):
56
- """
57
- Google Drive üzerinde bulunan bir Excel (.xlsx) veya Word (.docx) dosyasını okuyup içeriğini döndürür.
58
- """
59
- content = ""
60
- try:
61
- if file_path.lower().endswith((".xlsx", ".xls")):
62
- # Excel dosyasını oku
63
- df = pd.read_excel(file_path)
64
- # Excel içeriğini CSV formatında metne dönüştür (alternatif: istenen şekilde işlenebilir)
65
- content = df.to_csv(index=False)
66
- elif file_path.lower().endswith(".docx"):
67
- # Word dosyasını oku
68
- doc = docx.Document(file_path)
69
- full_text = [para.text for para in doc.paragraphs]
70
- content = "\n".join(full_text).strip()
71
- else:
72
- # Metin dosyası olarak oku (Excel/Word dışındaki dosyalar için genel durum)
73
- with open(file_path, 'r', encoding='utf-8') as f:
74
- content = f.read()
75
- except Exception as e:
76
- content = f"Hata: Dosya okunurken sorun oluştu - {e}"
77
- return content
78
 
79
- def log_to_huggingface(log_content):
80
- """
81
- Konuşma geçmişini veya belirli bir log bilgisini Hugging Face'e yükler.
82
- Bu örnekte işlev gövdesi boş bırakılmıştır; gerçek uygulamada API çağrısı yapılmalıdır.
83
- """
84
- try:
85
- # TODO: Hugging Face'e yükleme kodunu buraya entegre edin (örneğin huggingface_hub kullanarak).
86
- # Örnek: HfApi().upload_file(...) ile log_content içeriğini bir depo/dosya olarak yükleyebilirsiniz.
87
- pass
88
- except Exception as e:
89
- print(f"Hugging Face log yüklemede hata: {e}")
90
 
91
- def periodic_log(interval=300):
92
- """
93
- Sohbet geçmişini belirli aralıklarla (interval saniye) Hugging Face'e gönderen arkaplan görevi.
94
- """
95
- while True:
96
- time.sleep(interval)
97
- try:
98
- # Sistem mesajı haricindeki konuşmaları derle
99
- conversation_text = "\n".join(
100
- [f"{m['role'].capitalize()}: {m['content']}"
101
- for m in conversation_log if m.get('role') != 'system']
102
- )
103
- if conversation_text:
104
- log_to_huggingface(conversation_text)
105
- except Exception as e:
106
- print(f"Periyodik loglama hatası: {e}")
107
 
108
- def generate_text_response(conversation):
109
- """
110
- OpenAI ChatCompletion API ile güncel konuşma geçmişine göre metin yanıtı üretir.
111
- """
112
- try:
113
- response = openai.ChatCompletion.create(
114
- model=OPENAI_CHAT_MODEL,
115
- messages=conversation
116
- )
117
- answer = response['choices'][0]['message']['content'].strip()
118
- except Exception as e:
119
- # Hata durumunda özür dileyen bir mesaj döndür (hata mesajını da içerebilir)
120
- answer = f"Üzgünüm, yanıt üretirken bir hata oluştu: {e}"
121
- return answer
122
 
123
- def generate_audio_from_text(text):
124
- """
125
- Verilen metni OpenAI TTS modeliyle sese dönüştürür ve MP3 dosya yolunu döndürür.
126
- TTS başarısız olursa None döndürür.
127
- """
128
- try:
129
- audio_response = openai.Audio.create(
130
- model=TTS_MODEL,
131
- voice=TTS_VOICE,
132
- text=text,
133
- response_format="audio/mp3"
134
- )
135
- # audio_response içeriğinden ses verisini al (varsayılan anahtar adı 'audio' olarak düşünülmüştür)
136
- audio_content = audio_response.get('audio')
137
- if audio_content is None:
138
- # Bazı durumlarda audio_response doğrudan binary içerebilir, o durumda audio_content None olacaktır.
139
- audio_content = audio_response # Mümkünse direkt kullan
140
-
141
- # Elde edilen ses verisini bir MP3 dosyasına kaydet
142
- filename = f"response_{int(time.time())}.mp3"
143
- with open(filename, "wb") as f:
144
- f.write(audio_content)
145
- return filename
146
- except Exception as e:
147
- # Hata durumunda konsola logla ve None döndür
148
- print(f"TTS generation failed: {e}")
149
- return None
150
 
151
- # Gradio arayüzünü tanımla
152
- with gr.Blocks() as demo:
153
- gr.Markdown("## Trek Chatbot (Metin + Sesli Yanıt)") # Başlık
154
-
155
- chatbot = gr.Chatbot(label="Sohbet Geçmişi") # Sohbet geçmişini gösterecek bileşen
156
- user_input = gr.Textbox(label="Mesajınız") # Kullanıcıdan metin girişi
157
- send_btn = gr.Button("Gönder") # Mesaj gönderme butonu
158
- clear_btn = gr.Button("Konuşmayı Sıfırla") # Sohbeti temizleme butonu
159
-
160
- # Durum (state) değişkenleri: tam konuşma geçmişi (sistem mesajı dahil) ve sadece kullanıcı-asistan çiftleri (görüntüleme için)
161
- conversation_state = gr.State([{"role": "system", "content": SYSTEM_PROMPT}]) # Sistem mesajıyla başlat
162
- chat_history_state = gr.State([]) # Kullanıcı ve asistan mesaj çiftlerini tutacak (görüntüleme amacıyla)
163
-
164
- audio_output = gr.Audio(label="Sesli Yanıt", elem_id="audio_out") # Sesli yanıt için çıktı bileşeni
165
-
166
- # Global değişken (referans): konuşma geçmişi listesi (sistem dahil) - sohbet geçmişini kilitleyerek yönetiyoruz
167
- conversation_log = conversation_state.value # conversation_state içindeki liste nesnesine referans
168
-
169
- def respond(user_message, conversation_state_value, chat_history_value):
170
- """
171
- Kullanıcının mesajına yanıt üretir (metin ve ses).
172
- conversation_state_value: tam geçmiş (sistem mesajı dahil),
173
- chat_history_value: sohbet geçmişi (görüntüleme için kullanıcı-bot çiftleri).
174
- """
175
- # Kullanıcı mesajını konuşma geçmişine ekle (OpenAI modeline tam geçmişi vereceğiz)
176
- conversation_state_value.append({"role": "user", "content": user_message})
177
-
178
- bot_answer = None # Asistan yanıtı (metin)
179
-
180
- # Özel kurallar: Trek ürün stok/fiyat sorgusu
181
- if "stok" in user_message.lower() or "fiyat" in user_message.lower():
182
- # Mesajda stok veya fiyat kelimesi geçiyorsa, ürünü bulmaya çalış
183
- words = user_message.split()
184
- product_id = None
185
- for w in words:
186
- # Basit yaklaşım: mesajdaki ilk alfasayısal kelimeyi ürün kodu varsayıyoruz
187
- if w.isalnum():
188
- product_id = w
189
- break
190
- if product_id:
191
- price, stock = check_trek_product_info(product_id)
192
- if price is not None:
193
- # Ürün bulundu, stok ve fiyat bilgisi ile yanıt oluştur
194
- stock_status = "stokta var" if stock and stock != "0" else "stokta yok"
195
- bot_answer = f"{product_id} ürünü {stock_status}, fiyatı {price}."
196
- else:
197
- # Ürün bulunamadı
198
- bot_answer = "Üzgünüm, bu ürünün bilgisine ulaşılamadı."
199
-
200
- # Özel kurallar: Google Drive dosya okuma isteği
201
- if bot_answer is None and "drive" in user_message.lower():
202
- # Mesajda 'drive' geçiyorsa, son kelimeyi dosya yolu olarak al (örnek basit yaklaşım)
203
- file_path = user_message.split()[-1]
204
- file_content = read_file_from_drive(file_path)
205
- bot_answer = f"{file_path} dosyasının içeriği:\n{file_content}"
206
-
207
- # Genel durum: Özel bir durum yoksa, GPT modelinden yanıt al
208
- if bot_answer is None:
209
- bot_answer = generate_text_response(conversation_state_value)
210
-
211
- # Asistanın metin yanıtını konuşma geçmişine ekle (model bağlamı için)
212
- conversation_state_value.append({"role": "assistant", "content": bot_answer})
213
-
214
- # Hugging Face'e log kaydet (arkaplanda, asenkron şekilde)
215
- log_text = f"User: {user_message}\nAssistant: {bot_answer}\n"
216
- threading.Thread(target=log_to_huggingface, args=(log_text,)).start()
217
-
218
- # Metin yanıtını TTS ile sese dönüştür
219
- audio_file = generate_audio_from_text(bot_answer)
220
-
221
- # Sohbet geçmişini güncelle (görsel için kullanıcı-bot çiftini ekle)
222
- chat_history_value = chat_history_value or [] # None ise boş liste yap
223
- chat_history_value.append((user_message, bot_answer))
224
-
225
- # conversation_state_value ve chat_history_value, Gradio state'lerini güncellemek için döndürülür
226
- # audio_file ise ses dosyasının yolu ya da None (Gradio audio bileşenini güncellemek için)
227
- return conversation_state_value, chat_history_value, audio_file
228
-
229
- # Gönder butonuna tıklandığında veya Enter'a basıldığında respond fonksiyonunu çağır
230
- send_btn.click(
231
- respond,
232
- inputs=[user_input, conversation_state, chat_history_state],
233
- outputs=[conversation_state, chatbot, audio_output]
234
- )
235
- user_input.submit(
236
- respond,
237
- inputs=[user_input, conversation_state, chat_history_state],
238
- outputs=[conversation_state, chatbot, audio_output]
239
- )
240
-
241
- # Konuşmayı sıfırla (temizle) butonu işlevi
242
- def clear_history():
243
- """Sohbet geçmişini ve durumu sıfırlar."""
244
- return [{"role": "system", "content": SYSTEM_PROMPT}], [], None
245
- clear_btn.click(
246
- clear_history,
247
- inputs=None,
248
- outputs=[conversation_state, chatbot, audio_output],
249
- queue=False
250
- )
251
-
252
- # Arkaplanda periyodik loglama işlemini başlat (daemon thread, uygulamayı engellemez)
253
- threading.Thread(target=periodic_log, args=(300,), daemon=True).start()
254
 
255
- # Gradio arayüzünü başlat
256
- demo.launch()
 
 
 
1
  import gradio as gr
2
+ import requests
3
+ import os
4
+ from openai import OpenAI
 
 
 
 
 
 
 
 
 
 
5
 
6
+ # OpenAI API istemcisi
7
+ client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
 
 
 
 
 
8
 
9
+ # Chatbot fonksiyonunuzu ses üretimi ile birlikte güncelleyin
10
+ def chatbot_fn_tts(user_message, history):
11
+ text_response = ""
 
 
 
 
12
 
13
+ payload = {
14
+ "model": "gpt-4o",
15
+ "messages": history + [{"role": "user", "content": user_message}],
16
+ "temperature": 0.2,
17
+ "stream": False
18
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ chat_response = client.chat.completions.create(**payload)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
+ text_response = chat_response.choices[0].message.content
 
 
 
 
 
 
 
 
 
 
23
 
24
+ # TTS ses üretimi
25
+ response = client.audio.speech.create(
26
+ model="tts-1",
27
+ voice="nova",
28
+ input=text_response
29
+ )
 
 
 
 
 
 
 
 
 
 
30
 
31
+ audio_file_path = "tts_output.mp3"
32
+ response.stream_to_file(audio_file_path)
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
+ return text_response, audio_file_path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
+ # Gradio arayüzünü oluştur
37
+ iface = gr.Interface(
38
+ fn=chatbot_fn_tts,
39
+ inputs=["text", "state"],
40
+ outputs=["text", gr.Audio(type="filepath")],
41
+ title="Trek GPT-4o Mini TTS Chatbot",
42
+ description="Yazdığınız mesaja hem metin hem sesli yanıt alırsınız."
43
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
+ if __name__ == "__main__":
46
+ iface.launch(debug=True)