k96beni commited on
Commit
b0117f1
·
verified ·
1 Parent(s): e01c772

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +81 -62
app.py CHANGED
@@ -2,13 +2,14 @@ import os
2
  import pandas as pd
3
  import torch
4
  import gradio as gr
 
 
5
  from huggingface_hub import login, Repository
6
  from sentence_transformers import SentenceTransformer, util
7
 
8
  # -------------------------------
9
  # SÄTT GLOBAL GIT-IDENTITET
10
  # -------------------------------
11
- # Dessa kommandon ställer in din Git-identitet globalt.
12
  os.system('git config --global user.email "niklas.berg@chargenode.eu"')
13
  os.system('git config --global user.name "Niklas Berg"')
14
 
@@ -22,20 +23,19 @@ if not HF_TOKEN:
22
  # Logga in mot Hugging Face
23
  login(token=HF_TOKEN)
24
 
25
- # Repo-detaljer (ändra REPO_ID om det behövs)
26
- REPO_ID = "ChargeNodeEurope/Chatbot_4o_mini"
27
  REPO_LOCAL_PATH = "chatbot_faq_repo"
28
- FAQ_XLSX_PATH = "FAQ stadat.xlsx" # Excel-filen som innehåller FAQ-informationen
29
 
30
- # Klona repo:t (repo_type="space" eftersom det är en Hugging Face Space)
31
  repo = Repository(
32
  local_dir=REPO_LOCAL_PATH,
33
  clone_from=REPO_ID,
34
- repo_type="space",
35
  use_auth_token=HF_TOKEN
36
  )
37
 
38
- # Sökväg till FAQ Excel-filen
39
  faq_path = os.path.join(REPO_LOCAL_PATH, FAQ_XLSX_PATH)
40
  try:
41
  df = pd.read_excel(faq_path)
@@ -43,26 +43,22 @@ try:
43
  except Exception as e:
44
  raise FileNotFoundError(f"Kunde inte ladda FAQ-filen: {str(e)}")
45
 
46
- # Ladda Sentence Transformer-modellen för att skapa semantiska embeddings
47
  model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
48
-
49
- # Skapa embeddings för alla FAQ-frågor
50
  faq_questions = df["Fråga"].tolist()
51
  faq_embeddings = model.encode(faq_questions, convert_to_tensor=True)
52
 
53
-
54
  # -------------------------------
55
  # HJÄLPFUNKTIONER
56
  # -------------------------------
57
  def uppdatera_embeddings():
58
  """
59
- Uppdaterar FAQ-frågornas embeddings efter att DataFrame har ändrats.
60
  """
61
  global faq_questions, faq_embeddings, df
62
  faq_questions = df["Fråga"].tolist()
63
  faq_embeddings = model.encode(faq_questions, convert_to_tensor=True)
64
 
65
-
66
  def sök_faq(fråga):
67
  """
68
  Utför en semantisk sökning i FAQ och returnerar de tre bästa resultaten.
@@ -71,11 +67,9 @@ def sök_faq(fråga):
71
  if not fråga:
72
  return pd.DataFrame(columns=["Liknande fråga", "Svar", "Kategori", "Confidence"])
73
 
74
- # Skapa embedding för användarens fråga
75
  query_emb = model.encode(fråga, convert_to_tensor=True)
76
  cos_scores = util.cos_sim(query_emb, faq_embeddings)[0]
77
 
78
- # Hämta de tre högsta resultaten
79
  top_results = torch.topk(cos_scores, k=3)
80
  indices = top_results.indices.tolist()
81
  scores = top_results.values.tolist()
@@ -91,10 +85,10 @@ def sök_faq(fråga):
91
  })
92
  return pd.DataFrame(data)
93
 
94
-
95
  def lägg_till_faq(fråga, svar, kategori):
96
  """
97
- Lägger till en ny FAQ-post, sparar ändringar, pushar till repo:t och uppdaterar embeddings.
 
98
  """
99
  global df
100
  fråga = fråga.strip()
@@ -105,15 +99,12 @@ def lägg_till_faq(fråga, svar, kategori):
105
  return "Fråga, svar och kategori får inte vara tomma!"
106
 
107
  try:
108
- # Lägg till posten i DataFrame
109
  ny_rad = pd.DataFrame([[fråga, svar, kategori]], columns=["Fråga", "Svar", "Kategori"])
110
  df = pd.concat([df, ny_rad], ignore_index=True)
111
 
112
- # Spara ändringarna till Excel-filen
113
  df.to_excel(faq_path, index=False)
114
  uppdatera_embeddings()
115
 
116
- # Lägg till, commit och push med Git
117
  repo.git_add()
118
  repo.git_commit(f"Lade till FAQ: {fråga[:50]}...")
119
  repo.git_push()
@@ -122,14 +113,12 @@ def lägg_till_faq(fråga, svar, kategori):
122
  except Exception as e:
123
  return f"Fel vid uppdatering: {str(e)}"
124
 
125
-
126
  def visa_senaste_faq(antal=10):
127
  """
128
  Returnerar de senaste 'antal' FAQ-posterna.
129
  """
130
  return df.tail(antal)
131
 
132
-
133
  def uppdatera_faq(gammal_fråga, nytt_svar, ny_kategori):
134
  """
135
  Uppdaterar en befintlig FAQ-post (baserat på exakt matchning av 'Fråga').
@@ -162,7 +151,6 @@ def uppdatera_faq(gammal_fråga, nytt_svar, ny_kategori):
162
  except Exception as e:
163
  return f"Fel vid uppdatering: {str(e)}"
164
 
165
-
166
  def ta_bort_faq(fråga_att_radera):
167
  """
168
  Tar bort en FAQ-post baserat på en exakt matchning av 'Fråga'.
@@ -189,50 +177,81 @@ def ta_bort_faq(fråga_att_radera):
189
  except Exception as e:
190
  return f"Fel vid borttagning: {str(e)}"
191
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
 
193
  # -------------------------------
194
  # GRADIO-GRÄNSSNITT
195
  # -------------------------------
196
  with gr.Blocks() as demo:
197
  gr.Markdown("# Enkel FAQ Admin")
198
- gr.Markdown("Administrera FAQ-poster: Sök i befintliga frågor, lägg till, uppdatera eller ta bort.")
199
-
200
- # --- Sök i FAQ ---
201
- gr.Markdown("## Sök i FAQ")
202
- inp_question = gr.Textbox(label="Din fråga", placeholder="Ex: Hur startar jag en laddning?")
203
- btn_search = gr.Button("Sök")
204
- out_search = gr.Dataframe(label="Topp 3 resultat")
205
-
206
- btn_search.click(fn=sök_faq, inputs=inp_question, outputs=out_search)
207
-
208
- # --- Lägg till FAQ ---
209
- gr.Markdown("## Lägg till FAQ")
210
- add_question = gr.Textbox(label="Ny fråga")
211
- add_answer = gr.Textbox(label="Nytt svar")
212
- add_cat = gr.Textbox(label="Ny kategori")
213
- btn_add = gr.Button("Lägg till")
214
- out_add = gr.Textbox(label="Status")
215
- btn_add.click(fn=lägg_till_faq, inputs=[add_question, add_answer, add_cat], outputs=out_add)
216
-
217
- # --- Redigera / Ta bort FAQ ---
218
- gr.Markdown("## Redigera / Ta bort FAQ")
219
- existing_quests = gr.Dropdown(choices=df["Fråga"].tolist(), label="Befintliga frågor")
220
- new_answer = gr.Textbox(label="Nytt svar (valfritt)")
221
- new_cat = gr.Textbox(label="Ny kategori (valfritt)")
222
- btn_update = gr.Button("Uppdatera")
223
- out_update = gr.Textbox(label="Status")
224
-
225
- btn_delete = gr.Button("Ta bort")
226
- out_delete = gr.Textbox(label="Status")
227
-
228
- btn_update.click(fn=uppdatera_faq, inputs=[existing_quests, new_answer, new_cat], outputs=out_update)
229
- btn_delete.click(fn=ta_bort_faq, inputs=existing_quests, outputs=out_delete)
230
-
231
- # --- Visa senaste FAQ-poster ---
232
- gr.Markdown("## Visa senaste FAQ-poster")
233
- btn_show = gr.Button("Visa senaste 10")
234
- out_log = gr.Dataframe(label="Senaste poster")
235
- btn_show.click(fn=visa_senaste_faq, inputs=[], outputs=out_log)
 
 
 
 
 
236
 
237
  if __name__ == "__main__":
238
- demo.launch()
 
 
2
  import pandas as pd
3
  import torch
4
  import gradio as gr
5
+ import json # För att hantera JSON-data i loggfilen
6
+
7
  from huggingface_hub import login, Repository
8
  from sentence_transformers import SentenceTransformer, util
9
 
10
  # -------------------------------
11
  # SÄTT GLOBAL GIT-IDENTITET
12
  # -------------------------------
 
13
  os.system('git config --global user.email "niklas.berg@chargenode.eu"')
14
  os.system('git config --global user.name "Niklas Berg"')
15
 
 
23
  # Logga in mot Hugging Face
24
  login(token=HF_TOKEN)
25
 
26
+ # Repo-detaljer
27
+ REPO_ID = "ChargeNodeEurope/Chatbot_4o_mini"
28
  REPO_LOCAL_PATH = "chatbot_faq_repo"
29
+ FAQ_XLSX_PATH = "FAQ stadat.xlsx" # Excel-filen med FAQ-information
30
 
 
31
  repo = Repository(
32
  local_dir=REPO_LOCAL_PATH,
33
  clone_from=REPO_ID,
34
+ repo_type="space", # Ange "space" om det är en Hugging Face Space
35
  use_auth_token=HF_TOKEN
36
  )
37
 
38
+ # Ladda in FAQ-data från Excel-filen
39
  faq_path = os.path.join(REPO_LOCAL_PATH, FAQ_XLSX_PATH)
40
  try:
41
  df = pd.read_excel(faq_path)
 
43
  except Exception as e:
44
  raise FileNotFoundError(f"Kunde inte ladda FAQ-filen: {str(e)}")
45
 
46
+ # Ladda Sentence Transformer-modellen för semantiska embeddings
47
  model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
 
 
48
  faq_questions = df["Fråga"].tolist()
49
  faq_embeddings = model.encode(faq_questions, convert_to_tensor=True)
50
 
 
51
  # -------------------------------
52
  # HJÄLPFUNKTIONER
53
  # -------------------------------
54
  def uppdatera_embeddings():
55
  """
56
+ Uppdaterar FAQ-embeddings efter att FAQ-data har ändrats.
57
  """
58
  global faq_questions, faq_embeddings, df
59
  faq_questions = df["Fråga"].tolist()
60
  faq_embeddings = model.encode(faq_questions, convert_to_tensor=True)
61
 
 
62
  def sök_faq(fråga):
63
  """
64
  Utför en semantisk sökning i FAQ och returnerar de tre bästa resultaten.
 
67
  if not fråga:
68
  return pd.DataFrame(columns=["Liknande fråga", "Svar", "Kategori", "Confidence"])
69
 
 
70
  query_emb = model.encode(fråga, convert_to_tensor=True)
71
  cos_scores = util.cos_sim(query_emb, faq_embeddings)[0]
72
 
 
73
  top_results = torch.topk(cos_scores, k=3)
74
  indices = top_results.indices.tolist()
75
  scores = top_results.values.tolist()
 
85
  })
86
  return pd.DataFrame(data)
87
 
 
88
  def lägg_till_faq(fråga, svar, kategori):
89
  """
90
+ Lägger till en ny FAQ-post, uppdaterar Excel-filen, skapar nya embeddings
91
+ samt pushar ändringen till Hugging Face-repo:t.
92
  """
93
  global df
94
  fråga = fråga.strip()
 
99
  return "Fråga, svar och kategori får inte vara tomma!"
100
 
101
  try:
 
102
  ny_rad = pd.DataFrame([[fråga, svar, kategori]], columns=["Fråga", "Svar", "Kategori"])
103
  df = pd.concat([df, ny_rad], ignore_index=True)
104
 
 
105
  df.to_excel(faq_path, index=False)
106
  uppdatera_embeddings()
107
 
 
108
  repo.git_add()
109
  repo.git_commit(f"Lade till FAQ: {fråga[:50]}...")
110
  repo.git_push()
 
113
  except Exception as e:
114
  return f"Fel vid uppdatering: {str(e)}"
115
 
 
116
  def visa_senaste_faq(antal=10):
117
  """
118
  Returnerar de senaste 'antal' FAQ-posterna.
119
  """
120
  return df.tail(antal)
121
 
 
122
  def uppdatera_faq(gammal_fråga, nytt_svar, ny_kategori):
123
  """
124
  Uppdaterar en befintlig FAQ-post (baserat på exakt matchning av 'Fråga').
 
151
  except Exception as e:
152
  return f"Fel vid uppdatering: {str(e)}"
153
 
 
154
  def ta_bort_faq(fråga_att_radera):
155
  """
156
  Tar bort en FAQ-post baserat på en exakt matchning av 'Fråga'.
 
177
  except Exception as e:
178
  return f"Fel vid borttagning: {str(e)}"
179
 
180
+ def visa_logfil():
181
+ """
182
+ Läser in loggfilen och returnerar en DataFrame med de senaste 10 posterna:
183
+ Datum, UserID, Fråga (user_message) och Svar (bot_reply).
184
+ """
185
+ log_file_path = os.path.join("ChargeNodeEurope", "logfiles", "logs_v2", "conversation_log_v2.txt")
186
+ logs = []
187
+ try:
188
+ with open(log_file_path, "r", encoding="utf-8") as f:
189
+ for line in f:
190
+ line = line.strip()
191
+ if line:
192
+ log_entry = json.loads(line)
193
+ logs.append(log_entry)
194
+ # Sortera loggarna med nyaste först (baserat på timestamp)
195
+ logs_sorted = sorted(logs, key=lambda x: x["timestamp"], reverse=True)
196
+ latest10 = logs_sorted[:10]
197
+ df_logs = pd.DataFrame(latest10)
198
+ if not df_logs.empty:
199
+ # Välj och döp om de kolumner som ska visas
200
+ df_logs = df_logs[["timestamp", "user_id", "user_message", "bot_reply"]]
201
+ df_logs.columns = ["Datum", "UserID", "Fråga", "Svar"]
202
+ return df_logs
203
+ except Exception as e:
204
+ return pd.DataFrame({"Fel": [f"Fel vid inläsning av loggfil: {e}"]})
205
 
206
  # -------------------------------
207
  # GRADIO-GRÄNSSNITT
208
  # -------------------------------
209
  with gr.Blocks() as demo:
210
  gr.Markdown("# Enkel FAQ Admin")
211
+ gr.Markdown("Administrera FAQ-poster: Sök, lägg till, uppdatera eller ta bort FAQ samt visa loggposter.")
212
+
213
+ with gr.Tab("FAQ"):
214
+ # --- Sök i FAQ ---
215
+ gr.Markdown("## Sök i FAQ")
216
+ inp_question = gr.Textbox(label="Din fråga", placeholder="Ex: Hur startar jag en laddning?")
217
+ btn_search = gr.Button("Sök")
218
+ out_search = gr.Dataframe(label="Topp 3 resultat")
219
+ btn_search.click(fn=sök_faq, inputs=inp_question, outputs=out_search)
220
+
221
+ # --- Lägg till FAQ ---
222
+ gr.Markdown("## Lägg till FAQ")
223
+ add_question = gr.Textbox(label="Ny fråga")
224
+ add_answer = gr.Textbox(label="Nytt svar")
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
+ # --- Redigera / Ta bort FAQ ---
231
+ gr.Markdown("## Redigera / Ta bort FAQ")
232
+ existing_quests = gr.Dropdown(choices=df["Fråga"].tolist(), label="Befintliga frågor")
233
+ new_answer = gr.Textbox(label="Nytt svar (valfritt)")
234
+ new_cat = gr.Textbox(label="Ny kategori (valfritt)")
235
+ btn_update = gr.Button("Uppdatera")
236
+ out_update = gr.Textbox(label="Status")
237
+ btn_delete = gr.Button("Ta bort")
238
+ out_delete = gr.Textbox(label="Status")
239
+ btn_update.click(fn=uppdatera_faq, inputs=[existing_quests, new_answer, new_cat], outputs=out_update)
240
+ btn_delete.click(fn=ta_bort_faq, inputs=existing_quests, outputs=out_delete)
241
+
242
+ # --- Visa senaste FAQ-poster ---
243
+ gr.Markdown("## Visa senaste FAQ-poster")
244
+ btn_show = gr.Button("Visa senaste 10")
245
+ out_log = gr.Dataframe(label="Senaste poster")
246
+ btn_show.click(fn=visa_senaste_faq, inputs=[], outputs=out_log)
247
+
248
+ with gr.Tab("Logg"):
249
+ # --- Visa loggfilen ---
250
+ gr.Markdown("## Visa senast 10 loggposter")
251
+ btn_log = gr.Button("Visa loggfil")
252
+ out_logfil = gr.Dataframe(label="Senaste loggar")
253
+ btn_log.click(fn=visa_logfil, inputs=[], outputs=out_logfil)
254
 
255
  if __name__ == "__main__":
256
+ # Ange autentisering: username: ChargeNode, password: wer123
257
+ demo.launch(auth=[("ChargeNode", "wer123")])