k96beni commited on
Commit
44000f4
·
verified ·
1 Parent(s): d59a72d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +70 -95
app.py CHANGED
@@ -3,7 +3,6 @@ import json
3
  import pandas as pd
4
  import torch
5
  import gradio as gr
6
- import datetime
7
 
8
  from huggingface_hub import login, Repository
9
  from sentence_transformers import SentenceTransformer, util
@@ -17,7 +16,7 @@ if not HF_TOKEN:
17
 
18
  login(token=HF_TOKEN)
19
 
20
- REPO_ID = "ChargeNodeEurope/Chatbot_4o_mini" # Exempel-ID
21
  REPO_LOCAL_PATH = "chatbot_faq_repo"
22
  FAQ_XLSX_PATH = "FAQ stadat.xlsx"
23
 
@@ -35,20 +34,19 @@ try:
35
  except Exception as e:
36
  raise FileNotFoundError(f"Kunde inte ladda FAQ-filen: {str(e)}")
37
 
38
- # Ladda Sentence Transformer-modellen
39
  model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
40
 
41
  # Skapa embeddings av alla FAQ-frågor en gång
42
  faq_questions = df["Fråga"].tolist()
43
  faq_embeddings = model.encode(faq_questions, convert_to_tensor=True)
44
 
45
-
46
  # ================================
47
- # HJÄLPFUNKTIONER
48
  # ================================
49
  def uppdatera_embeddings():
50
  """
51
- Uppdatera FAQ-embeddings om FAQ-DataFrame ändras.
52
  """
53
  global faq_questions, faq_embeddings, df
54
  faq_questions = df["Fråga"].tolist()
@@ -56,21 +54,21 @@ def uppdatera_embeddings():
56
 
57
  def sök_faq(fråga):
58
  """
59
- Gör en semantisk sökning i FAQ och returnerar topp 3 resultat.
60
  """
61
  fråga = fråga.strip()
62
  if not fråga:
63
  return pd.DataFrame(columns=["Liknande fråga", "Svar", "Kategori", "Confidence"])
64
-
65
- # Skapa embedding för sökfrågan
66
  query_emb = model.encode(fråga, convert_to_tensor=True)
67
  cos_scores = util.cos_sim(query_emb, faq_embeddings)[0]
68
-
69
- # Hämta de 3 bästa resultaten
70
  top_results = torch.topk(cos_scores, k=3)
71
  indices = top_results.indices.tolist()
72
  scores = top_results.values.tolist()
73
-
74
  data = []
75
  for idx, score in zip(indices, scores):
76
  row = df.iloc[idx]
@@ -84,7 +82,7 @@ def sök_faq(fråga):
84
 
85
  def lägg_till_faq(fråga, svar, kategori):
86
  """
87
- Lägger till en ny FAQ-post, sparar och synkroniserar med Hugging Face-repot.
88
  """
89
  global df
90
  fråga = fråga.strip()
@@ -95,13 +93,13 @@ def lägg_till_faq(fråga, svar, kategori):
95
  return "Fråga, svar och kategori får inte vara tomma!"
96
 
97
  try:
98
- # Lägg till den nya FAQ-posten i DataFrame
99
  ny_rad = pd.DataFrame([[fråga, svar, kategori]], columns=["Fråga", "Svar", "Kategori"])
100
  df = pd.concat([df, ny_rad], ignore_index=True)
101
 
102
- # Spara ändringar till Excel-filen
103
  df.to_excel(faq_path, index=False)
104
- uppdatera_embeddings() # Uppdatera embeddings
105
 
106
  repo.git_add()
107
  repo.git_commit(f"Lade till FAQ: {fråga[:50]}...")
@@ -112,15 +110,9 @@ def lägg_till_faq(fråga, svar, kategori):
112
  return f"Fel vid uppdatering: {str(e)}"
113
 
114
  def visa_senaste_faq(antal=10):
115
- """
116
- Returnerar de senaste {antal} FAQ-posterna (från Excel-filen).
117
- """
118
  return df.tail(antal)
119
 
120
  def uppdatera_faq(gammal_fråga, nytt_svar, ny_kategori):
121
- """
122
- Uppdaterar FAQ-posten med ny information.
123
- """
124
  global df
125
  gammal_fråga = gammal_fråga.strip()
126
  nytt_svar = nytt_svar.strip()
@@ -150,9 +142,6 @@ def uppdatera_faq(gammal_fråga, nytt_svar, ny_kategori):
150
  return f"Fel vid uppdatering: {str(e)}"
151
 
152
  def ta_bort_faq(fråga_att_radera):
153
- """
154
- Tar bort en vald FAQ-post.
155
- """
156
  global df
157
  fråga_att_radera = fråga_att_radera.strip()
158
  if not fråga_att_radera:
@@ -201,79 +190,65 @@ def visa_logfil():
201
  except Exception as e:
202
  return pd.DataFrame({"Fel": [f"Fel vid inläsning av loggfil: {e}"]})
203
 
204
-
205
  # ================================
206
  # GRADIO-GRÄNSSNITT
207
  # ================================
208
- with gr.Blocks() as demo:
209
- # --- Login-sektionen ---
210
- with gr.Column(visible=True) as login_container:
211
- gr.Markdown("## Logga in")
212
- login_username = gr.Textbox(label="Användarnamn")
213
- login_password = gr.Textbox(label="Lösenord", type="password")
214
- login_button = gr.Button("Logga in")
215
- login_status = gr.Textbox(label="Status")
216
-
217
- # --- Huvudapplikationen (gömmer tills inloggning lyckas) ---
218
- with gr.Column(visible=False) as main_container:
219
- gr.Markdown("# Enkel FAQ Admin")
220
- gr.Markdown("Administrera FAQ-poster, sök i befintliga frågor, lägg till, uppdatera eller ta bort.")
221
-
222
- # ---- Sök i FAQ ----
223
- gr.Markdown("## Sök i FAQ")
224
- inp_question = gr.Textbox(label="Din fråga", placeholder="Ex: Hur startar jag en laddning?")
225
- btn_search = gr.Button("Sök")
226
- out_search = gr.Dataframe(label="Topp 3 resultat")
227
- btn_search.click(fn=sök_faq, inputs=inp_question, outputs=out_search)
228
-
229
- # ---- Lägg till FAQ ----
230
- gr.Markdown("## Lägg till FAQ")
231
- add_question = gr.Textbox(label="Ny fråga")
232
- add_answer = gr.Textbox(label="Nytt svar")
233
- add_cat = gr.Textbox(label="Ny kategori")
234
- btn_add = gr.Button("Lägg till")
235
- out_add = gr.Textbox(label="Status")
236
- btn_add.click(fn=lägg_till_faq, inputs=[add_question, add_answer, add_cat], outputs=out_add)
237
-
238
- # ---- Redigera / Ta bort FAQ ----
239
- gr.Markdown("## Redigera / Ta bort FAQ")
240
- existing_quests = gr.Dropdown(choices=df["Fråga"].tolist(), label="Befintliga frågor")
241
- new_answer = gr.Textbox(label="Nytt svar (valfritt)")
242
- new_cat = gr.Textbox(label="Ny kategori (valfritt)")
243
- btn_update = gr.Button("Uppdatera")
244
- out_update = gr.Textbox(label="Status")
245
- btn_delete = gr.Button("Ta bort")
246
- out_delete = gr.Textbox(label="Status")
247
- btn_update.click(fn=uppdatera_faq, inputs=[existing_quests, new_answer, new_cat], outputs=out_update)
248
- btn_delete.click(fn=ta_bort_faq, inputs=existing_quests, outputs=out_delete)
249
-
250
- # ---- Visa senaste FAQ-poster ----
251
- gr.Markdown("## Visa senaste FAQ-poster")
252
- btn_show = gr.Button("Visa senaste 10")
253
- out_faq_log = gr.Dataframe(label="Senaste poster")
254
- btn_show.click(fn=visa_senaste_faq, inputs=[], outputs=out_faq_log)
255
-
256
- # ---- Visa loggfil (senaste 10 konversationer) ----
257
- gr.Markdown("## Visa loggfil")
258
- btn_log = gr.Button("Visa loggfil")
259
- out_logfil = gr.Dataframe(label="Senaste loggar")
260
- btn_log.click(fn=visa_logfil, inputs=[], outputs=out_logfil)
261
-
262
- # --- Inloggningsverifiering ---
263
- def verify_login(username, password):
264
- """
265
- Verifierar inloggningsuppgifterna mot miljövariablerna APP_USERNAME och APP_PASSWORD.
266
- """
267
- valid_username = os.getenv("APP_USERNAME")
268
- valid_password = os.getenv("APP_PASSWORD")
269
- if username == valid_username and password == valid_password:
270
- return "Inloggning lyckades!", gr.update(visible=False), gr.update(visible=True)
271
- else:
272
- return "Felaktiga inloggningsuppgifter!", gr.update(visible=True), gr.update(visible=False)
273
-
274
- login_button.click(fn=verify_login,
275
- inputs=[login_username, login_password],
276
- outputs=[login_status, login_container, main_container])
277
 
278
  if __name__ == "__main__":
279
  demo.launch()
 
3
  import pandas as pd
4
  import torch
5
  import gradio as gr
 
6
 
7
  from huggingface_hub import login, Repository
8
  from sentence_transformers import SentenceTransformer, util
 
16
 
17
  login(token=HF_TOKEN)
18
 
19
+ REPO_ID = "ChargeNodeEurope/Chatbot_4o_mini" # Exempel
20
  REPO_LOCAL_PATH = "chatbot_faq_repo"
21
  FAQ_XLSX_PATH = "FAQ stadat.xlsx"
22
 
 
34
  except Exception as e:
35
  raise FileNotFoundError(f"Kunde inte ladda FAQ-filen: {str(e)}")
36
 
37
+ # Ladda Sentence Transformer
38
  model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
39
 
40
  # Skapa embeddings av alla FAQ-frågor en gång
41
  faq_questions = df["Fråga"].tolist()
42
  faq_embeddings = model.encode(faq_questions, convert_to_tensor=True)
43
 
 
44
  # ================================
45
+ # HJÄLPFUNKTIONER
46
  # ================================
47
  def uppdatera_embeddings():
48
  """
49
+ Uppdatera embeddings efter att FAQ-DataFrame har ändrats.
50
  """
51
  global faq_questions, faq_embeddings, df
52
  faq_questions = df["Fråga"].tolist()
 
54
 
55
  def sök_faq(fråga):
56
  """
57
+ Gör en enkel semantisk sökning i FAQ och returnerar topp 3 resultat.
58
  """
59
  fråga = fråga.strip()
60
  if not fråga:
61
  return pd.DataFrame(columns=["Liknande fråga", "Svar", "Kategori", "Confidence"])
62
+
63
+ # Skapa embedding för query
64
  query_emb = model.encode(fråga, convert_to_tensor=True)
65
  cos_scores = util.cos_sim(query_emb, faq_embeddings)[0]
66
+
67
+ # Hämta topp 3
68
  top_results = torch.topk(cos_scores, k=3)
69
  indices = top_results.indices.tolist()
70
  scores = top_results.values.tolist()
71
+
72
  data = []
73
  for idx, score in zip(indices, scores):
74
  row = df.iloc[idx]
 
82
 
83
  def lägg_till_faq(fråga, svar, kategori):
84
  """
85
+ Lägger till en ny fråga i df, sparar och pushar, uppdaterar embeddings.
86
  """
87
  global df
88
  fråga = fråga.strip()
 
93
  return "Fråga, svar och kategori får inte vara tomma!"
94
 
95
  try:
96
+ # Lägg till i DataFrame
97
  ny_rad = pd.DataFrame([[fråga, svar, kategori]], columns=["Fråga", "Svar", "Kategori"])
98
  df = pd.concat([df, ny_rad], ignore_index=True)
99
 
100
+ # Spara och pusha
101
  df.to_excel(faq_path, index=False)
102
+ uppdatera_embeddings() # Skapa nya embeddings
103
 
104
  repo.git_add()
105
  repo.git_commit(f"Lade till FAQ: {fråga[:50]}...")
 
110
  return f"Fel vid uppdatering: {str(e)}"
111
 
112
  def visa_senaste_faq(antal=10):
 
 
 
113
  return df.tail(antal)
114
 
115
  def uppdatera_faq(gammal_fråga, nytt_svar, ny_kategori):
 
 
 
116
  global df
117
  gammal_fråga = gammal_fråga.strip()
118
  nytt_svar = nytt_svar.strip()
 
142
  return f"Fel vid uppdatering: {str(e)}"
143
 
144
  def ta_bort_faq(fråga_att_radera):
 
 
 
145
  global df
146
  fråga_att_radera = fråga_att_radera.strip()
147
  if not fråga_att_radera:
 
190
  except Exception as e:
191
  return pd.DataFrame({"Fel": [f"Fel vid inläsning av loggfil: {e}"]})
192
 
 
193
  # ================================
194
  # GRADIO-GRÄNSSNITT
195
  # ================================
196
+
197
+ # Anpassad CSS för att göra gränssnittet snyggare
198
+ custom_css = """
199
+ body {background-color: #f7f7f7; font-family: Arial, sans-serif;}
200
+ h1, h2, h3 {font-family: Helvetica, sans-serif; color: #2a9d8f; text-align: center;}
201
+ .gradio-container {max-width: 900px; margin: auto; padding: 20px;}
202
+ .gr-button {background-color: #264653; color: #fff;}
203
+ """
204
+
205
+ with gr.Blocks(css=custom_css, title="Enkel FAQ Admin") as demo:
206
+ gr.Markdown("<h1>Enkel FAQ Admin</h1>")
207
+ gr.Markdown("<p style='text-align: center;'>Administrera FAQ-poster: sök i befintliga frågor, lägg till, uppdatera, ta bort och visa loggfil.</p>")
208
+
209
+ with gr.Tabs():
210
+ # Tab: Sök i FAQ
211
+ with gr.TabItem("Sök i FAQ"):
212
+ with gr.Row():
213
+ inp_question = gr.Textbox(label="Din fråga", placeholder="Ex: Hur startar jag en laddning?")
214
+ btn_search = gr.Button("Sök")
215
+ out_search = gr.Dataframe(label="Topp 3 resultat")
216
+ btn_search.click(fn=sök_faq, inputs=inp_question, outputs=out_search)
217
+
218
+ # Tab: Lägg till FAQ
219
+ with gr.TabItem("Lägg till FAQ"):
220
+ with gr.Row():
221
+ add_question = gr.Textbox(label="Ny fråga")
222
+ with gr.Row():
223
+ add_answer = gr.Textbox(label="Nytt svar")
224
+ with gr.Row():
225
+ add_cat = gr.Textbox(label="Ny kategori")
226
+ btn_add = gr.Button("Lägg till")
227
+ out_add = gr.Textbox(label="Status")
228
+ btn_add.click(fn=lägg_till_faq, inputs=[add_question, add_answer, add_cat], outputs=out_add)
229
+
230
+ # Tab: Redigera / Ta bort FAQ
231
+ with gr.TabItem("Redigera / Ta bort FAQ"):
232
+ with gr.Row():
233
+ existing_quests = gr.Dropdown(choices=df["Fråga"].tolist(), label="Befintliga frågor")
234
+ with gr.Row():
235
+ new_answer = gr.Textbox(label="Nytt svar (valfritt)")
236
+ with gr.Row():
237
+ new_cat = gr.Textbox(label="Ny kategori (valfritt)")
238
+ btn_update = gr.Button("Uppdatera")
239
+ out_update = gr.Textbox(label="Status")
240
+ btn_update.click(fn=uppdatera_faq, inputs=[existing_quests, new_answer, new_cat], outputs=out_update)
241
+
242
+ gr.Markdown("#### Eller ta bort en FAQ-post:")
243
+ btn_delete = gr.Button("Ta bort")
244
+ out_delete = gr.Textbox(label="Status")
245
+ btn_delete.click(fn=ta_bort_faq, inputs=existing_quests, outputs=out_delete)
246
+
247
+ # Tab: Visa FAQ-loggfilen
248
+ with gr.TabItem("Loggfil"):
249
+ btn_show_log = gr.Button("Visa senaste 10 poster")
250
+ out_log = gr.Dataframe(label="Loggfil")
251
+ btn_show_log.click(fn=visa_logfil, inputs=[], outputs=out_log)
 
 
 
 
 
 
 
 
 
 
 
 
 
252
 
253
  if __name__ == "__main__":
254
  demo.launch()