Dev4zz commited on
Commit
1c73a09
·
verified ·
1 Parent(s): 19e9e7f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +13 -18
app.py CHANGED
@@ -10,11 +10,11 @@ APIFY_TOKEN = os.getenv("APIFY_TOKEN")
10
  HF_TOKEN = os.getenv("HF_TOKEN")
11
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
12
 
13
- # Validasi token saat startup
14
  if not HF_TOKEN:
15
  print("⚠️ WARNING: HF_TOKEN is not set! Sentiment analysis will fail.")
16
- if not GEMINI_KEY:
17
- print("⚠️ WARNING: GEMINI_KEY is not set! Gemini insights will fail.")
18
  if not APIFY_TOKEN:
19
  print("⚠️ WARNING: APIFY_TOKEN is not set! Scraping will fail.")
20
 
@@ -31,7 +31,7 @@ app.add_middleware(
31
  allow_headers=["*"],
32
  )
33
 
34
- # Hugging Face — nlptown model (always active, 1-5 star output, supports Indonesian)
35
  HF_API_URL = "https://router.huggingface.co/hf-inference/models/nlptown/bert-base-multilingual-uncased-sentiment"
36
  HF_HEADERS = {"Authorization": f"Bearer {HF_TOKEN}"}
37
 
@@ -68,13 +68,11 @@ def analyze_sentiment(ulasan_list):
68
 
69
  # nlptown returns [[{"label": "5 stars", "score": 0.5}, ...]]
70
  if isinstance(res, list) and len(res) > 0:
71
- # Get the top prediction
72
  predictions = res[0] if isinstance(res[0], list) else res
73
  if predictions and isinstance(predictions[0], dict):
74
  top_label = predictions[0].get("label", "3 stars")
75
  stars = int(top_label[0]) # "5 stars" → 5
76
 
77
- # Map stars to sentiment: 1-2=neg, 3=neu, 4-5=pos
78
  if stars >= 4:
79
  sentiment = "pos"
80
  elif stars <= 2:
@@ -93,8 +91,7 @@ def analyze_sentiment(ulasan_list):
93
 
94
  for asp in matched_aspects:
95
  raw_scores[asp][sentiment] += 1
96
-
97
- print(f"✅ Sentiment: {stars} stars → {sentiment} | Aspects: {[a[:4] for a in matched_aspects]}")
98
  else:
99
  print(f"HF unexpected format: {str(predictions)[:100]}")
100
  else:
@@ -110,7 +107,6 @@ def analyze_sentiment(ulasan_list):
110
  def get_advanced_insights(ulasan_list):
111
  try:
112
  gabungan_ulasan = " | ".join(ulasan_list[:8])
113
- # Prompt disesuaikan sedikit agar Llama 3 lebih menurut
114
  prompt = f"""
115
  Kamu adalah analis bisnis restoran. Analisis ulasan berikut: {gabungan_ulasan}.
116
  Kamu WAJIB mengembalikan respon HANYA dalam format JSON murni ini:
@@ -129,9 +125,9 @@ def get_advanced_insights(ulasan_list):
129
  }
130
 
131
  payload = {
132
- "model": "llama3-8b-8192", # Model Llama 3 yang sangat cepat
133
  "messages": [{"role": "user", "content": prompt}],
134
- "response_format": {"type": "json_object"}, # Memaksa output berupa JSON
135
  "temperature": 0.5
136
  }
137
 
@@ -139,7 +135,6 @@ def get_advanced_insights(ulasan_list):
139
 
140
  if response.status_code == 200:
141
  data = response.json()
142
- # Parsing output khas arsitektur OpenAI/Groq
143
  t = data["choices"][0]["message"]["content"]
144
  return json.loads(t)
145
  else:
@@ -152,7 +147,7 @@ def get_advanced_insights(ulasan_list):
152
  "kata_kunci_negatif": ["Server Sibuk"],
153
  "rekomendasi": [{"judul": "Gunakan Fallback", "deskripsi": "Server LLM sedang sibuk.", "prioritas": "Low"}]
154
  }
155
-
156
  # --- 4. ENDPOINT ---
157
  @app.post("/analyze")
158
  async def analyze_realtime(request: Request):
@@ -160,7 +155,7 @@ async def analyze_realtime(request: Request):
160
  body = await request.json()
161
  target_url = body.get("url")
162
 
163
- # Scraper (15 ulasan — sesuaikan dengan batas proses AI)
164
  run = apify_client.actor("compass/google-maps-reviews-scraper").call(
165
  run_input={"startUrls": [{"url": target_url}], "maxReviews": 100, "language": "id"}
166
  )
@@ -181,7 +176,7 @@ async def analyze_realtime(request: Request):
181
 
182
  # Proses AI
183
  raw_scores = analyze_sentiment(ulasan_teks_saja)
184
- gemini_data = get_advanced_insights(ulasan_teks_saja)
185
 
186
  # Kalkulasi
187
  sentiment_results = []
@@ -208,11 +203,11 @@ async def analyze_realtime(request: Request):
208
  "overall_sentiment": {"positive": over_p, "neutral": over_neu, "negative": over_n},
209
  "sentiment_score": sentiment_results,
210
  "kata_kunci": {
211
- "positif": gemini_data.get("kata_kunci_positif", []),
212
- "negatif": gemini_data.get("kata_kunci_negatif", [])
213
  },
214
  "contoh_review": ulasan_lengkap[:6],
215
- "rekomendasi_list": gemini_data.get("rekomendasi", [])
216
  }
217
  }
218
  except Exception as e:
 
10
  HF_TOKEN = os.getenv("HF_TOKEN")
11
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
12
 
13
+ # Validasi token saat startup (Gemini sudah dihapus)
14
  if not HF_TOKEN:
15
  print("⚠️ WARNING: HF_TOKEN is not set! Sentiment analysis will fail.")
16
+ if not GROQ_API_KEY:
17
+ print("⚠️ WARNING: GROQ_API_KEY is not set! Llama 3 insights will fail.")
18
  if not APIFY_TOKEN:
19
  print("⚠️ WARNING: APIFY_TOKEN is not set! Scraping will fail.")
20
 
 
31
  allow_headers=["*"],
32
  )
33
 
34
+ # Hugging Face — nlptown model
35
  HF_API_URL = "https://router.huggingface.co/hf-inference/models/nlptown/bert-base-multilingual-uncased-sentiment"
36
  HF_HEADERS = {"Authorization": f"Bearer {HF_TOKEN}"}
37
 
 
68
 
69
  # nlptown returns [[{"label": "5 stars", "score": 0.5}, ...]]
70
  if isinstance(res, list) and len(res) > 0:
 
71
  predictions = res[0] if isinstance(res[0], list) else res
72
  if predictions and isinstance(predictions[0], dict):
73
  top_label = predictions[0].get("label", "3 stars")
74
  stars = int(top_label[0]) # "5 stars" → 5
75
 
 
76
  if stars >= 4:
77
  sentiment = "pos"
78
  elif stars <= 2:
 
91
 
92
  for asp in matched_aspects:
93
  raw_scores[asp][sentiment] += 1
94
+
 
95
  else:
96
  print(f"HF unexpected format: {str(predictions)[:100]}")
97
  else:
 
107
  def get_advanced_insights(ulasan_list):
108
  try:
109
  gabungan_ulasan = " | ".join(ulasan_list[:8])
 
110
  prompt = f"""
111
  Kamu adalah analis bisnis restoran. Analisis ulasan berikut: {gabungan_ulasan}.
112
  Kamu WAJIB mengembalikan respon HANYA dalam format JSON murni ini:
 
125
  }
126
 
127
  payload = {
128
+ "model": "llama3-8b-8192",
129
  "messages": [{"role": "user", "content": prompt}],
130
+ "response_format": {"type": "json_object"},
131
  "temperature": 0.5
132
  }
133
 
 
135
 
136
  if response.status_code == 200:
137
  data = response.json()
 
138
  t = data["choices"][0]["message"]["content"]
139
  return json.loads(t)
140
  else:
 
147
  "kata_kunci_negatif": ["Server Sibuk"],
148
  "rekomendasi": [{"judul": "Gunakan Fallback", "deskripsi": "Server LLM sedang sibuk.", "prioritas": "Low"}]
149
  }
150
+
151
  # --- 4. ENDPOINT ---
152
  @app.post("/analyze")
153
  async def analyze_realtime(request: Request):
 
155
  body = await request.json()
156
  target_url = body.get("url")
157
 
158
+ # Scraper
159
  run = apify_client.actor("compass/google-maps-reviews-scraper").call(
160
  run_input={"startUrls": [{"url": target_url}], "maxReviews": 100, "language": "id"}
161
  )
 
176
 
177
  # Proses AI
178
  raw_scores = analyze_sentiment(ulasan_teks_saja)
179
+ insights_data = get_advanced_insights(ulasan_teks_saja) # Variabel diganti dari gemini_data
180
 
181
  # Kalkulasi
182
  sentiment_results = []
 
203
  "overall_sentiment": {"positive": over_p, "neutral": over_neu, "negative": over_n},
204
  "sentiment_score": sentiment_results,
205
  "kata_kunci": {
206
+ "positif": insights_data.get("kata_kunci_positif", []),
207
+ "negatif": insights_data.get("kata_kunci_negatif", [])
208
  },
209
  "contoh_review": ulasan_lengkap[:6],
210
+ "rekomendasi_list": insights_data.get("rekomendasi", [])
211
  }
212
  }
213
  except Exception as e: