Ogghey commited on
Commit
57cd8cf
ยท
verified ยท
1 Parent(s): e97e0b7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -17
app.py CHANGED
@@ -1,10 +1,12 @@
1
  import os
2
  import shutil
3
  from fastapi import FastAPI, Request
 
4
  from sentence_transformers import SentenceTransformer, util
5
  import torch
6
  import requests
7
- # Rate_limit
 
8
  from slowapi import Limiter, _rate_limit_exceeded_handler
9
  from slowapi.util import get_remote_address
10
  from slowapi.errors import RateLimitExceeded
@@ -15,34 +17,26 @@ app = FastAPI()
15
  app.state.limiter = limiter
16
  app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
17
 
18
- # ๐Ÿ” Paksa semua cache ke path aman di Hugging Face Spaces
19
  HF_CACHE = "/tmp/hf"
20
  os.environ["TRANSFORMERS_CACHE"] = HF_CACHE
21
  os.environ["HF_HOME"] = HF_CACHE
22
  os.makedirs(HF_CACHE, exist_ok=True)
23
 
24
- # โœ… Bersihkan cache jika terkunci
25
  if os.path.exists(f"{HF_CACHE}/models--sentence-transformers--paraphrase-MiniLM-L3-v2.lock"):
26
  os.remove(f"{HF_CACHE}/models--sentence-transformers--paraphrase-MiniLM-L3-v2.lock")
27
  if os.path.exists(f"{HF_CACHE}/models--sentence-transformers--paraphrase-MiniLM-L3-v2"):
28
  shutil.rmtree(f"{HF_CACHE}/models--sentence-transformers--paraphrase-MiniLM-L3-v2", ignore_errors=True)
29
 
30
- # ๐Ÿ” Supabase
31
  SUPABASE_URL = "https://olbjfxlclotxtnpjvpfj.supabase.co"
32
  SUPABASE_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im9sYmpmeGxjbG90eHRucGp2cGZqIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTIyMzYwMDEsImV4cCI6MjA2NzgxMjAwMX0.7q_o5DCFEAAysnWXMChH4MI5qNhIVc4OgpT5JvgYxc0"
33
 
34
-
35
- # Inisialisasi rate limiter dan FastAPI
36
- limiter = Limiter(key_func=get_remote_address)
37
- app = FastAPI()
38
- app.state.limiter = limiter
39
- app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
40
-
41
- # ๐Ÿ”„ Gunakan model kecil dan cepat
42
  model = SentenceTransformer("sentence-transformers/paraphrase-MiniLM-L3-v2")
43
 
44
- app = FastAPI()
45
-
46
  def get_faq_from_supabase(uid):
47
  url = f"{SUPABASE_URL}/rest/v1/faq_texts?uid=eq.{uid}"
48
  headers = {
@@ -59,15 +53,16 @@ def get_faq_from_supabase(uid):
59
  print("โŒ Supabase error:", e)
60
  return []
61
 
 
62
  @app.post("/predict")
63
  @limiter.limit("5/minute")
64
  async def predict(request: Request):
65
  body = await request.json()
66
  uid, question = body.get("data", [None, None])
67
-
68
  if not uid or not question:
69
  return {"data": ["UID atau pertanyaan tidak valid."]}
70
-
71
  faqs = get_faq_from_supabase(uid)
72
  if not faqs:
73
  return {"data": ["FAQ tidak ditemukan untuk UID ini."]}
@@ -81,4 +76,53 @@ async def predict(request: Request):
81
  similarity = util.pytorch_cos_sim(query_embedding, embeddings)
82
  best_idx = torch.argmax(similarity).item()
83
 
84
- return {"data": [answers[best_idx]]}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import os
2
  import shutil
3
  from fastapi import FastAPI, Request
4
+ from fastapi.responses import JSONResponse
5
  from sentence_transformers import SentenceTransformer, util
6
  import torch
7
  import requests
8
+
9
+ # Rate limit
10
  from slowapi import Limiter, _rate_limit_exceeded_handler
11
  from slowapi.util import get_remote_address
12
  from slowapi.errors import RateLimitExceeded
 
17
  app.state.limiter = limiter
18
  app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
19
 
20
+ # ๐Ÿ” Paksa cache aman untuk Hugging Face Spaces
21
  HF_CACHE = "/tmp/hf"
22
  os.environ["TRANSFORMERS_CACHE"] = HF_CACHE
23
  os.environ["HF_HOME"] = HF_CACHE
24
  os.makedirs(HF_CACHE, exist_ok=True)
25
 
26
+ # Bersihkan cache model jika terkunci
27
  if os.path.exists(f"{HF_CACHE}/models--sentence-transformers--paraphrase-MiniLM-L3-v2.lock"):
28
  os.remove(f"{HF_CACHE}/models--sentence-transformers--paraphrase-MiniLM-L3-v2.lock")
29
  if os.path.exists(f"{HF_CACHE}/models--sentence-transformers--paraphrase-MiniLM-L3-v2"):
30
  shutil.rmtree(f"{HF_CACHE}/models--sentence-transformers--paraphrase-MiniLM-L3-v2", ignore_errors=True)
31
 
32
+ # Supabase
33
  SUPABASE_URL = "https://olbjfxlclotxtnpjvpfj.supabase.co"
34
  SUPABASE_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im9sYmpmeGxjbG90eHRucGp2cGZqIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTIyMzYwMDEsImV4cCI6MjA2NzgxMjAwMX0.7q_o5DCFEAAysnWXMChH4MI5qNhIVc4OgpT5JvgYxc0"
35
 
36
+ # Model
 
 
 
 
 
 
 
37
  model = SentenceTransformer("sentence-transformers/paraphrase-MiniLM-L3-v2")
38
 
39
+ # ๐Ÿ” Ambil FAQ berdasarkan UID
 
40
  def get_faq_from_supabase(uid):
41
  url = f"{SUPABASE_URL}/rest/v1/faq_texts?uid=eq.{uid}"
42
  headers = {
 
53
  print("โŒ Supabase error:", e)
54
  return []
55
 
56
+ # ๐Ÿ”ฎ Endpoint prediksi jawaban dari pertanyaan user
57
  @app.post("/predict")
58
  @limiter.limit("5/minute")
59
  async def predict(request: Request):
60
  body = await request.json()
61
  uid, question = body.get("data", [None, None])
62
+
63
  if not uid or not question:
64
  return {"data": ["UID atau pertanyaan tidak valid."]}
65
+
66
  faqs = get_faq_from_supabase(uid)
67
  if not faqs:
68
  return {"data": ["FAQ tidak ditemukan untuk UID ini."]}
 
76
  similarity = util.pytorch_cos_sim(query_embedding, embeddings)
77
  best_idx = torch.argmax(similarity).item()
78
 
79
+ return {"data": [answers[best_idx]]}
80
+
81
+ # ๐Ÿงน Hapus satu pesan berdasarkan ID
82
+ @app.post("/delete_chat")
83
+ async def delete_chat(request: Request):
84
+ body = await request.json()
85
+ message_id = body.get("id")
86
+
87
+ if not message_id:
88
+ return JSONResponse({"error": "ID pesan wajib diisi."}, status_code=400)
89
+
90
+ url = f"{SUPABASE_URL}/rest/v1/chat_logs?id=eq.{message_id}"
91
+ headers = {
92
+ "apikey": SUPABASE_KEY,
93
+ "Authorization": f"Bearer {SUPABASE_KEY}",
94
+ "Content-Type": "application/json",
95
+ "Prefer": "return=representation"
96
+ }
97
+
98
+ try:
99
+ r = requests.delete(url, headers=headers)
100
+ r.raise_for_status()
101
+ return {"message": f"Pesan dengan ID {message_id} berhasil dihapus."}
102
+ except Exception as e:
103
+ print("โŒ Gagal hapus pesan:", e)
104
+ return JSONResponse({"error": "Gagal menghapus pesan."}, status_code=500)
105
+
106
+ # ๐Ÿงผ Hapus semua pesan milik user tertentu
107
+ @app.post("/delete_all_by_uid")
108
+ async def delete_all_by_uid(request: Request):
109
+ body = await request.json()
110
+ uid = body.get("uid")
111
+
112
+ if not uid:
113
+ return JSONResponse({"error": "UID wajib diisi."}, status_code=400)
114
+
115
+ url = f"{SUPABASE_URL}/rest/v1/chat_logs?uid=eq.{uid}"
116
+ headers = {
117
+ "apikey": SUPABASE_KEY,
118
+ "Authorization": f"Bearer {SUPABASE_KEY}",
119
+ "Content-Type": "application/json",
120
+ "Prefer": "return=representation"
121
+ }
122
+
123
+ try:
124
+ r = requests.delete(url, headers=headers)
125
+ r.raise_for_status()
126
+ return {"message": f"Semua pesan dengan UID {uid} berhasil dihapus."}
127
+ except Exception as e:
128
+ return JSONResponse({"error": str(e)}, status_code=500)