SamiKoen commited on
Commit
8b61968
·
verified ·
1 Parent(s): ebac9eb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +109 -53
app.py CHANGED
@@ -4,19 +4,16 @@ import json
4
  import requests
5
  import xml.etree.ElementTree as ET
6
 
7
- # os.getenv("API_URL") + "/generate_stream"
8
  API_URL = "https://api.openai.com/v1/chat/completions"
9
  OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
10
 
 
11
  url = 'https://www.trekbisiklet.com.tr/output/8582384479'
12
-
13
  response = requests.get(url)
14
-
15
-
16
  root = ET.fromstring(response.content)
17
 
18
  products = []
19
-
20
  for item in root.findall('item'):
21
  if item.find('isOptionOfAProduct').text == '1':
22
  if item.find('stockAmount').text > '0':
@@ -26,7 +23,7 @@ for item in root.findall('item'):
26
  stockAmount = "stokta"
27
  price = item.find('priceWithTax').text
28
  item_info = (stockAmount, price)
29
- # name: ilk kelime (marka), item_info: (stok adedi, fiyat)
30
  products.append((name, item_info, full_name))
31
 
32
 
@@ -36,18 +33,19 @@ def predict(system_msg, inputs, top_p, temperature, chat_counter, chatbot=[], hi
36
  "Authorization": f"Bearer {OPENAI_API_KEY}"
37
  }
38
  print(f"system message is ^^ {system_msg}")
39
- initial_message = [{"role": "user", "content": f"{inputs}"},]
 
 
 
 
 
 
 
40
 
41
- multi_turn_message = [{"role": "system", "content": "Sen bir Bıke Finder asistanısın. Görevin insanların doğru bisiklet modeli seçimini sağlamak. Kişilere sorucağın bir takım sorularala, kişileri tanıyıp, onlara stoklarımızda bulunan bisikletlerin model, boylarını tavsiye edeceksin. "} ,
42
- {"role": "system", "content": "Merhaba, ben Trek Stok Danısmanı Asistanıyım! Size en uygun Trek bisiklet modelini belirleyebilmem için birkaç sorum olacak. Verdiğiniz bilgiler doğrultusunda, elimizdeki güncel stoklardan ihtiyaçlarınıza en uygun modeli seçip, satin alma sürecine yonlendirecegim. Unutmayin, tum Trek bisikletlerimiz omur boyu garantilidir! Adim 1: Bisiklet Kategorisi - Hangi tur Trek bisikletiyle ilgileniyorsunuz? Lutfen asagidaki seceneklerden birini belirtiniz: Yol Bisikleti ornek: Trek Emonda, Trek Domane; Dag Bisikleti ornek: Trek Fuel EX, Trek Remedy, Trek Procaliber; Hibrit Sehir Bisikleti; Gravel Bisikleti ornek: Trek Checkpoint; Elektrikli Bisikleti ornek: Trek Powerfly, Trek Allant+. Adim 2: Kullanim Amaci - Bisikletinizi hangi amaclarla kullanmayi planliyorsunuz? ornek: gunluk ulasim, spor, uzun mesafe turlari, yaris, offroad maceralari, dag yollari. Adim 3: Beklentiler - Trek bisikletinizde hangi ozellikler sizin icin en onemli? ornek: performans, konfor, dayaniklilik, teknoloji yenilik, estetk, diger. Adim 4: Zemin Kosullari - Bisikletinizi hangi zeminlerde kullanacaksiniz? ornek: sehir ici asfalt, hafif engebeli parkurlar, orman dogal parkurlar, zorlu dag yollari offroad, karisik kullanim. Adim 5: Fiziksel Olculer - Dogru model ve cerceve boyutunu belirleyebilmem icin lutfen boyunuzu ve ic bacak boyunuzu paylasir misiniz? ornek: Boyum 180 cm, ic bacak boyum 85 cm. Adim 6: Ek Tercihler - Ek olarak, bisikletinizde tercih ettiginiz baska ozellikler var mi? ornek: ekstra donanim, ozel renk, aksesuar tercihi veya butce araliginiz. Adim 7: Oneri ve Satisa Yonlendirme - Verdigimiz bilgiler dogrultusunda, stoklarimizda bulunan ve ihtiyaclariniza en uygun olan Onerilen Model modelini oneriyorum. Bu model, kisa teknik ozellikler, kullanim avantajlari ve hedeflenen zemin alan ile beklentilerinize hitap ediyor. Ustelik, tum Trek bisikletlerimiz omur boyu garantilidir! Su an stok durumumuz: Stokta mevcut, Sinirli stok. Urun detaylari ve satin alma islemi icin lutfen su linke tiklayin: Trek Onerilen Model Urun Sayfasi https:orneksite.comtrek-ornek-model. Kargo ve Teslimat - Siparisiniz odeme onayindan sonra en gec 24 saat icinde paketlenip kargoya verilir; Yuritici Kargo, MNG veya Aras Kargo ile gonderim yapilir. Kargo takip numarasi SMS ve eposta ile iletilecek; gonderim sureci 3-5 is gunu surer. Belirli tutar uzerindeki siparislerde ucretsiz kargo kampanyasi uygulanir. Lutfen yukaridaki linke tiklayarak satin alma isleminizi tamamlayin. Herhangi bir sorunuz veya ek isteginiz olursa, ben buradayim. Hadi, siparisinizi tamamlayalim ve maceraya baslayalim!"} ,
43
- {"role": "system", "content": "Stokları ve fiyatları https://www.trekbisiklet.com.tr den bakacaksın, diğer markalarla ilgigi soru gelirse kibarca cevaplayamayacağını ve trek in neden farklı olduğunu anlat. Yol bisikletlerinde Türkiye stoklarımızda, Madone, Domane, Emonda, CheckMate, CheckPoint ve SpeedConcept modelleri bulunuyor. Dağ bisikletlerinde ise Marlin, Procaliber, Supercaliber modeller, full amortisörlülerde ise Fuel Ex modeli bulunmakta. Şehir kullanımı için FX ve DS modelini stoklarda bulunduruyoruz. "} ]
44
  messages = multi_turn_message
45
- input_words = []
46
- for input in inputs.split():
47
- input_words.append(str(input).lower())
48
 
49
  for product_info in products:
50
-
51
  if product_info[0] in input_words:
52
  new_msg = f"{product_info[2]} {product_info[1][0]} ve fiyatı EURO {product_info[1][1]}"
53
  print(new_msg)
@@ -55,55 +53,48 @@ def predict(system_msg, inputs, top_p, temperature, chat_counter, chatbot=[], hi
55
  messages.append(product_msg)
56
 
57
  for data in chatbot:
58
- user = {}
59
- user["role"] = "user"
60
- user["content"] = data[0]
61
- assistant = {}
62
- assistant["role"] = "assistant"
63
- assistant["content"] = data[1]
64
  messages.append(user)
65
  messages.append(assistant)
66
- temp = {}
67
- temp["role"] = "user"
68
- temp["content"] = inputs
69
- messages.append(temp)
70
 
71
-
72
- payload = {"model": "gpt-4o", "messages": messages, "temperature": 0.7,
73
- "top_p": 0.9, "n": 1, "stream": True, "presence_penalty": 0, "frequency_penalty": 0,}
 
 
 
 
 
 
 
74
 
75
  chat_counter += 1
76
-
77
  history.append(inputs)
78
  print(f"Logging : payload is - {payload}")
79
 
80
- response = requests.post(API_URL, headers=headers,
81
- json=payload, stream=True)
82
  print(f"Logging : response code - {response}")
 
83
  token_counter = 0
84
  partial_words = ""
85
-
86
  counter = 0
87
  for chunk in response.iter_lines():
88
-
89
  if counter == 0:
90
  counter += 1
91
  continue
92
-
93
  if chunk.decode():
94
  chunk = chunk.decode()
95
-
96
  if len(chunk) > 12 and "content" in json.loads(chunk[6:])['choices'][0]['delta']:
97
- partial_words = partial_words + \
98
- json.loads(chunk[6:])['choices'][0]["delta"]["content"]
99
  if token_counter == 0:
100
  history.append(" " + partial_words)
101
  else:
102
  history[-1] = partial_words
103
- chat = [(history[i], history[i + 1]) for i in range(0,
104
- len(history) - 1, 2)] # convert to tuples of list
105
  token_counter += 1
106
- # resembles {chatbot: chat, state: history}
107
  yield chat, history, chat_counter, response
108
 
109
 
@@ -119,35 +110,100 @@ def set_visible_true():
119
  return gr.update(visible=False)
120
 
121
 
122
- theme_addon_msg = ""
123
- system_msg_info = ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  theme = gr.themes.Base(
125
- neutral_hue="blue",
126
  text_size="sm",
127
  spacing_size="sm",
128
  )
129
 
130
- with gr.Blocks(theme=theme) as demo:
131
- ...
132
- ...
 
133
  with gr.Column(elem_id="col_container"):
134
  with gr.Accordion("", open=False, visible=False):
135
  system_msg = gr.Textbox(value="")
136
  new_msg = gr.Textbox(value="")
137
  accordion_msg = gr.HTML(value="", visible=False)
 
138
  chatbot = gr.Chatbot(label='Trek Bike Finder', elem_id="chatbot")
139
  inputs = gr.Textbox(
140
- placeholder="Buraya yazın, istediğniz modeli beraber bulalım.", show_label=False)
141
  state = gr.State([])
142
  with gr.Accordion("", open=False, visible=False):
143
- top_p = gr.Slider(minimum=-0, maximum=1.0, value=0.5,
144
- step=0.05, interactive=False, visible=False)
145
- temperature = gr.Slider(
146
- minimum=-0, maximum=5.0, value=0.1, step=0.1, interactive=False, visible=False)
147
  chat_counter = gr.Number(value=0, visible=False, precision=0)
148
 
149
- inputs.submit(predict, [system_msg, inputs, top_p, temperature, chat_counter, chatbot, state], [chatbot, state, chat_counter])
 
 
 
 
150
  inputs.submit(reset_textbox, [], [inputs])
151
 
152
-
153
- demo.queue(max_size=10).launch(debug=True)
 
4
  import requests
5
  import xml.etree.ElementTree as ET
6
 
7
+ # API URL ve API KEY ayarları
8
  API_URL = "https://api.openai.com/v1/chat/completions"
9
  OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
10
 
11
+ # Ürün verilerini çekme işlemi
12
  url = 'https://www.trekbisiklet.com.tr/output/8582384479'
 
13
  response = requests.get(url)
 
 
14
  root = ET.fromstring(response.content)
15
 
16
  products = []
 
17
  for item in root.findall('item'):
18
  if item.find('isOptionOfAProduct').text == '1':
19
  if item.find('stockAmount').text > '0':
 
23
  stockAmount = "stokta"
24
  price = item.find('priceWithTax').text
25
  item_info = (stockAmount, price)
26
+ # name: ilk kelime (marka), item_info: (stok durumu, fiyat)
27
  products.append((name, item_info, full_name))
28
 
29
 
 
33
  "Authorization": f"Bearer {OPENAI_API_KEY}"
34
  }
35
  print(f"system message is ^^ {system_msg}")
36
+ initial_message = [{"role": "user", "content": f"{inputs}"}]
37
+
38
+ multi_turn_message = [
39
+ {"role": "system", "content": "Sen bir Bıke Finder asistanısın. Görevin insanların doğru bisiklet modeli seçimini sağlamak. Kişilere sorucağın bir takım sorularala, kişileri tanıyıp, onlara stoklarımızda bulunan bisikletlerin model, boylarını tavsiye edeceksin."},
40
+ {"role": "system", "content": "Merhaba, ben Trek Stok Danısmanı Asistanıyım! Size en uygun Trek bisiklet modelini belirleyebilmem için birkaç sorum olacak. Verdiğiniz bilgiler doğrultusunda, elimizdeki güncel stoklardan ihtiyaçlarınıza en uygun modeli seçip, satin alma sürecine yonlendirecegim. Unutmayin, tum Trek bisikletlerimiz omur boyu garantilidir! Adim 1: Bisiklet Kategorisi - Hangi tur Trek bisikletiyle ilgileniyorsunuz? Lutfen asagidaki seceneklerden birini belirtiniz: Yol Bisikleti ornek: Trek Emonda, Trek Domane; Dag Bisikleti ornek: Trek Fuel EX, Trek Remedy, Trek Procaliber; Hibrit Sehir Bisikleti; Gravel Bisikleti ornek: Trek Checkpoint; Elektrikli Bisikleti ornek: Trek Powerfly, Trek Allant+."},
41
+ {"role": "system", "content": "Adim 2: Kullanim Amaci - Bisikletinizi hangi amaclarla kullanmayi planliyorsunuz? ornek: gunluk ulasim, spor, uzun mesafe turlari, yaris, offroad maceralari, dag yollari. Adim 3: Beklentiler - Trek bisikletinizde hangi ozellikler sizin icin en onemli? ornek: performans, konfor, dayaniklilik, teknoloji yenilik, estetk, diger. Adim 4: Zemin Kosullari - Bisikletinizi hangi zeminlerde kullanacaksiniz? ornek: sehir ici asfalt, hafif engebeli parkurlar, orman dogal parkurlar, zorlu dag yollari offroad, karisik kullanim. Adim 5: Fiziksel Olculer - Dogru model ve cerceve boyutunu belirleyebilmem icin lutfen boyunuzu ve ic bacak boyunuzu paylasir misiniz? ornek: Boyum 180 cm, ic bacak boyum 85 cm. Adim 6: Ek Tercihler - Ek olarak, bisikletinizde tercih ettiginiz baska ozellikler var mi? ornek: ekstra donanim, ozel renk, aksesuar tercihi veya butce araliginiz. Adim 7: Oneri ve Satisa Yonlendirme - Verdigimiz bilgiler dogrultusunda, stoklarimizda bulunan ve ihtiyaclariniza en uygun olan Onerilen Model modelini oneriyorum. Bu model, kisa teknik ozellikler, kullanim avantajlari ve hedeflenen zemin alan ile beklentilerinize hitap ediyor. Ustelik, tum Trek bisikletlerimiz omur boyu garantilidir! Su an stok durumumuz: Stokta mevcut, Sinirli stok. Urun detaylari ve satin alma islemi icin lutfen su linke tiklayin: Trek Onerilen Model Urun Sayfasi https:orneksite.comtrek-ornek-model. Kargo ve Teslimat - Siparisiniz odeme onayindan sonra en gec 24 saat icinde paketlenip kargoya verilir; Yuritici Kargo, MNG veya Aras Kargo ile gonderim yapilir. Kargo takip numarasi SMS ve eposta ile iletilecek; gonderim sureci 3-5 is gunu surer. Belirli tutar uzerindeki siparislerde ucretsiz kargo kampanyasi uygulanir."},
42
+ {"role": "system", "content": "Stokları ve fiyatları https://www.trekbisiklet.com.tr den bakacaksın, diğer markalarla ilgigi soru gelirse kibarca cevaplayamayacağını ve trek in neden farklı olduğunu anlat. Yol bisikletlerinde Türkiye stoklarımızda, Madone, Domane, Emonda, CheckMate, CheckPoint ve SpeedConcept modelleri bulunuyor. Dağ bisikletlerinde ise Marlin, Procaliber, Supercaliber modeller, full amortisörlülerde ise Fuel Ex modeli bulunmakta. Şehir kullanımı için FX ve DS modelini stoklarda bulunduruyoruz."}
43
+ ]
44
 
 
 
 
45
  messages = multi_turn_message
46
+ input_words = [str(word).lower() for word in inputs.split()]
 
 
47
 
48
  for product_info in products:
 
49
  if product_info[0] in input_words:
50
  new_msg = f"{product_info[2]} {product_info[1][0]} ve fiyatı EURO {product_info[1][1]}"
51
  print(new_msg)
 
53
  messages.append(product_msg)
54
 
55
  for data in chatbot:
56
+ user = {"role": "user", "content": data[0]}
57
+ assistant = {"role": "assistant", "content": data[1]}
 
 
 
 
58
  messages.append(user)
59
  messages.append(assistant)
60
+
61
+ messages.append({"role": "user", "content": inputs})
 
 
62
 
63
+ payload = {
64
+ "model": "gpt-4o",
65
+ "messages": messages,
66
+ "temperature": 0.7,
67
+ "top_p": 0.9,
68
+ "n": 1,
69
+ "stream": True,
70
+ "presence_penalty": 0,
71
+ "frequency_penalty": 0,
72
+ }
73
 
74
  chat_counter += 1
 
75
  history.append(inputs)
76
  print(f"Logging : payload is - {payload}")
77
 
78
+ response = requests.post(API_URL, headers=headers, json=payload, stream=True)
 
79
  print(f"Logging : response code - {response}")
80
+
81
  token_counter = 0
82
  partial_words = ""
 
83
  counter = 0
84
  for chunk in response.iter_lines():
 
85
  if counter == 0:
86
  counter += 1
87
  continue
 
88
  if chunk.decode():
89
  chunk = chunk.decode()
 
90
  if len(chunk) > 12 and "content" in json.loads(chunk[6:])['choices'][0]['delta']:
91
+ partial_words += json.loads(chunk[6:])['choices'][0]["delta"]["content"]
 
92
  if token_counter == 0:
93
  history.append(" " + partial_words)
94
  else:
95
  history[-1] = partial_words
96
+ chat = [(history[i], history[i + 1]) for i in range(0, len(history) - 1, 2)]
 
97
  token_counter += 1
 
98
  yield chat, history, chat_counter, response
99
 
100
 
 
110
  return gr.update(visible=False)
111
 
112
 
113
+ # WhatsApp tarzı görünüm için özel CSS
114
+ css = """
115
+ /* Chat Başlığı: WhatsApp koyu yeşili */
116
+ .chat-header {
117
+ background-color: #075e54;
118
+ color: #fff;
119
+ padding: 15px;
120
+ text-align: center;
121
+ font-size: 20px;
122
+ font-weight: bold;
123
+ }
124
+
125
+ /* Chat penceresi: arka plan rengi */
126
+ #chatbot {
127
+ background-color: #ece5dd;
128
+ border: none;
129
+ padding: 10px;
130
+ }
131
+
132
+ /* Kullanıcı mesajı (sağa hizalı, açık yeşil) */
133
+ .chat-bubble.user {
134
+ background-color: #dcf8c6 !important;
135
+ align-self: flex-end;
136
+ border-radius: 20px;
137
+ padding: 10px 15px;
138
+ margin: 8px 0;
139
+ max-width: 70%;
140
+ word-wrap: break-word;
141
+ }
142
+
143
+ /* Bot mesajı (sola hizalı, beyaz) */
144
+ .chat-bubble.bot {
145
+ background-color: #fff !important;
146
+ align-self: flex-start;
147
+ border: 1px solid #ccc;
148
+ border-radius: 20px;
149
+ padding: 10px 15px;
150
+ margin: 8px 0;
151
+ max-width: 70%;
152
+ word-wrap: break-word;
153
+ }
154
+
155
+ /* Mesaj gönderme alanı */
156
+ .chat-input-container {
157
+ display: flex;
158
+ padding: 10px;
159
+ border-top: 1px solid #ddd;
160
+ background-color: #f0f0f0;
161
+ }
162
+
163
+ /* Gönder butonu */
164
+ .send-button {
165
+ background-color: #075e54;
166
+ border: none;
167
+ color: #fff;
168
+ padding: 10px 15px;
169
+ margin-left: 10px;
170
+ border-radius: 20px;
171
+ font-size: 16px;
172
+ cursor: pointer;
173
+ }
174
+ """
175
+
176
+ # Tema ayarını güncelliyoruz: neutral_hue 'green' ile WhatsApp benzeri yeşil ton
177
  theme = gr.themes.Base(
178
+ neutral_hue="green",
179
  text_size="sm",
180
  spacing_size="sm",
181
  )
182
 
183
+ with gr.Blocks(theme=theme, css=css) as demo:
184
+ # WhatsApp tarzı chat başlığı
185
+ gr.Markdown("<div class='chat-header'>Trek Bike Finder Chatbot</div>")
186
+
187
  with gr.Column(elem_id="col_container"):
188
  with gr.Accordion("", open=False, visible=False):
189
  system_msg = gr.Textbox(value="")
190
  new_msg = gr.Textbox(value="")
191
  accordion_msg = gr.HTML(value="", visible=False)
192
+ # Gradio'nun Chatbot bileşeni; özel CSS #chatbot ile stil veriyoruz
193
  chatbot = gr.Chatbot(label='Trek Bike Finder', elem_id="chatbot")
194
  inputs = gr.Textbox(
195
+ placeholder="Buraya yazın, istediğiniz modeli beraber bulalım.", show_label=False)
196
  state = gr.State([])
197
  with gr.Accordion("", open=False, visible=False):
198
+ top_p = gr.Slider(minimum=0, maximum=1.0, value=0.5, step=0.05, interactive=False, visible=False)
199
+ temperature = gr.Slider(minimum=0, maximum=5.0, value=0.1, step=0.1, interactive=False, visible=False)
 
 
200
  chat_counter = gr.Number(value=0, visible=False, precision=0)
201
 
202
+ inputs.submit(
203
+ predict,
204
+ [system_msg, inputs, top_p, temperature, chat_counter, chatbot, state],
205
+ [chatbot, state, chat_counter]
206
+ )
207
  inputs.submit(reset_textbox, [], [inputs])
208
 
209
+ demo.queue(max_size=10).launch(debug=True)