MASSJ77 commited on
Commit
e75b765
·
verified ·
1 Parent(s): ea9db0b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -9
app.py CHANGED
@@ -23,17 +23,18 @@ def fetch_user_activity(user_id):
23
  response = supabase.table("user_activity").select("*").eq("actor_user_id", user_id).execute()
24
  return response.data
25
 
 
26
  def fetch_safe_content():
27
  # Posts
28
  posts = supabase.table("posts").select("id, caption").execute().data
29
  moderated_posts = supabase.table("content_moderation").select("post_id, result, post_type").eq("post_type","post").execute().data
30
- safe_posts = {p["post_id"] for p in moderated_posts if p["result"]=="safe"}
31
  safe_post_ids = [p["id"] for p in posts if (p["id"] in safe_posts) or (p["id"] not in [m["post_id"] for m in moderated_posts])]
32
 
33
  # Trendz
34
  trendz = supabase.table("trendz").select("id, caption").execute().data
35
  moderated_trendz = supabase.table("content_moderation").select("post_id, result, post_type").eq("post_type","trendz").execute().data
36
- safe_trendz = {t["post_id"] for t in moderated_trendz if t["result"]=="safe"}
37
  safe_trendz_ids = [t["id"] for t in trendz if (t["id"] in safe_trendz) or (t["id"] not in [m["post_id"] for m in moderated_trendz])]
38
 
39
  return safe_post_ids, safe_trendz_ids, posts, trendz
@@ -43,25 +44,36 @@ def recommend(user_id, top_n=5):
43
  activities = fetch_user_activity(user_id)
44
  safe_post_ids, safe_trendz_ids, posts, trendz = fetch_safe_content()
45
 
46
- summaries = [a["content_summary"] for a in activities if a["content_summary"]]
 
 
 
 
 
47
 
 
48
  post_scores = {}
49
  for p in posts:
50
  if p["id"] in safe_post_ids:
51
- score = sum([p["caption"].lower().count(word.lower()) for word in summaries for word in word.split()])
 
52
  post_scores[p["id"]] = score
53
 
 
54
  trendz_scores = {}
55
  for t in trendz:
56
  if t["id"] in safe_trendz_ids:
57
- score = sum([t["caption"].lower().count(word.lower()) for word in summaries for word in word.split()])
 
58
  trendz_scores[t["id"]] = score
59
 
60
  recommended_posts = [pid for pid,_ in sorted(post_scores.items(), key=lambda x:x[1], reverse=True)[:top_n]]
61
  recommended_trendz = [tid for tid,_ in sorted(trendz_scores.items(), key=lambda x:x[1], reverse=True)[:top_n]]
62
 
 
63
  if not recommended_posts and safe_post_ids:
64
  recommended_posts = list(np.random.choice(safe_post_ids, min(top_n, len(safe_post_ids)), replace=False))
 
65
  if not recommended_trendz and safe_trendz_ids:
66
  recommended_trendz = list(np.random.choice(safe_trendz_ids, min(top_n, len(safe_trendz_ids)), replace=False))
67
 
@@ -87,9 +99,9 @@ def store_recommendations(user_id, recommended_posts, recommended_trendz):
87
  def root():
88
  return {"message": "AI Recommender API is running"}
89
 
 
90
  @app.get("/recommend/all")
91
  def recommend_all(x_api_key: str = Header(None)):
92
- # ✅ Security check
93
  if x_api_key != API_TOKEN:
94
  raise HTTPException(status_code=403, detail="Forbidden")
95
 
@@ -98,16 +110,14 @@ def recommend_all(x_api_key: str = Header(None)):
98
  for u in users:
99
  posts, trendz = recommend(u["id"])
100
  store_recommendations(u["id"], posts, trendz)
 
101
  return {"message": f"✅ Updated recommendations for {len(users)} users"}
102
  except Exception as e:
103
  return {"error": str(e)}
104
 
105
 
106
-
107
-
108
  @app.get("/recommend/{user_id}")
109
  def recommend_single_user(user_id: str, x_api_key: str = Header(None)):
110
- # ✅ Security check
111
  if x_api_key != API_TOKEN:
112
  raise HTTPException(status_code=403, detail="Forbidden")
113
 
@@ -123,3 +133,55 @@ def recommend_single_user(user_id: str, x_api_key: str = Header(None)):
123
  }
124
  except Exception as e:
125
  raise HTTPException(status_code=500, detail=str(e))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  response = supabase.table("user_activity").select("*").eq("actor_user_id", user_id).execute()
24
  return response.data
25
 
26
+
27
  def fetch_safe_content():
28
  # Posts
29
  posts = supabase.table("posts").select("id, caption").execute().data
30
  moderated_posts = supabase.table("content_moderation").select("post_id, result, post_type").eq("post_type","post").execute().data
31
+ safe_posts = {p["post_id"] for p in moderated_posts if p["result"] == "safe"}
32
  safe_post_ids = [p["id"] for p in posts if (p["id"] in safe_posts) or (p["id"] not in [m["post_id"] for m in moderated_posts])]
33
 
34
  # Trendz
35
  trendz = supabase.table("trendz").select("id, caption").execute().data
36
  moderated_trendz = supabase.table("content_moderation").select("post_id, result, post_type").eq("post_type","trendz").execute().data
37
+ safe_trendz = {t["post_id"] for t in moderated_trendz if t["result"] == "safe"}
38
  safe_trendz_ids = [t["id"] for t in trendz if (t["id"] in safe_trendz) or (t["id"] not in [m["post_id"] for m in moderated_trendz])]
39
 
40
  return safe_post_ids, safe_trendz_ids, posts, trendz
 
44
  activities = fetch_user_activity(user_id)
45
  safe_post_ids, safe_trendz_ids, posts, trendz = fetch_safe_content()
46
 
47
+ summaries = [a["content_summary"] for a in activities if a.get("content_summary")]
48
+
49
+ # Flatten keywords
50
+ keywords = []
51
+ for summary in summaries:
52
+ keywords.extend(summary.lower().split())
53
 
54
+ # Post scoring
55
  post_scores = {}
56
  for p in posts:
57
  if p["id"] in safe_post_ids:
58
+ caption = (p.get("caption") or "").lower()
59
+ score = sum(caption.count(word) for word in keywords)
60
  post_scores[p["id"]] = score
61
 
62
+ # Trendz scoring
63
  trendz_scores = {}
64
  for t in trendz:
65
  if t["id"] in safe_trendz_ids:
66
+ caption = (t.get("caption") or "").lower()
67
+ score = sum(caption.count(word) for word in keywords)
68
  trendz_scores[t["id"]] = score
69
 
70
  recommended_posts = [pid for pid,_ in sorted(post_scores.items(), key=lambda x:x[1], reverse=True)[:top_n]]
71
  recommended_trendz = [tid for tid,_ in sorted(trendz_scores.items(), key=lambda x:x[1], reverse=True)[:top_n]]
72
 
73
+ # fallback random safe content if no match
74
  if not recommended_posts and safe_post_ids:
75
  recommended_posts = list(np.random.choice(safe_post_ids, min(top_n, len(safe_post_ids)), replace=False))
76
+
77
  if not recommended_trendz and safe_trendz_ids:
78
  recommended_trendz = list(np.random.choice(safe_trendz_ids, min(top_n, len(safe_trendz_ids)), replace=False))
79
 
 
99
  def root():
100
  return {"message": "AI Recommender API is running"}
101
 
102
+
103
  @app.get("/recommend/all")
104
  def recommend_all(x_api_key: str = Header(None)):
 
105
  if x_api_key != API_TOKEN:
106
  raise HTTPException(status_code=403, detail="Forbidden")
107
 
 
110
  for u in users:
111
  posts, trendz = recommend(u["id"])
112
  store_recommendations(u["id"], posts, trendz)
113
+
114
  return {"message": f"✅ Updated recommendations for {len(users)} users"}
115
  except Exception as e:
116
  return {"error": str(e)}
117
 
118
 
 
 
119
  @app.get("/recommend/{user_id}")
120
  def recommend_single_user(user_id: str, x_api_key: str = Header(None)):
 
121
  if x_api_key != API_TOKEN:
122
  raise HTTPException(status_code=403, detail="Forbidden")
123
 
 
133
  }
134
  except Exception as e:
135
  raise HTTPException(status_code=500, detail=str(e))
136
+
137
+
138
+ # ========================================
139
+ # 4️⃣ NEW — POSTS ONLY ENDPOINT
140
+ # ========================================
141
+ @app.get("/recommend/posts/{user_id}")
142
+ def recommend_user_posts(user_id: str, x_api_key: str = Header(None)):
143
+ if x_api_key != API_TOKEN:
144
+ raise HTTPException(status_code=403, detail="Forbidden")
145
+
146
+ try:
147
+ posts, _ = recommend(user_id)
148
+
149
+ supabase.table("user_recommendations").upsert({
150
+ "user_id": user_id,
151
+ "recommended_post_ids": posts,
152
+ "generated_at": datetime.now(timezone.utc).isoformat()
153
+ }).execute()
154
+
155
+ return {
156
+ "message": "✅ Post recommendations generated successfully",
157
+ "user_id": user_id,
158
+ "recommended_posts": posts
159
+ }
160
+ except Exception as e:
161
+ raise HTTPException(status_code=500, detail=str(e))
162
+
163
+
164
+ # ========================================
165
+ # 5️⃣ NEW — TRENDZ ONLY ENDPOINT
166
+ # ========================================
167
+ @app.get("/recommend/trendz/{user_id}")
168
+ def recommend_user_trendz(user_id: str, x_api_key: str = Header(None)):
169
+ if x_api_key != API_TOKEN:
170
+ raise HTTPException(status_code=403, detail="Forbidden")
171
+
172
+ try:
173
+ _, trendz = recommend(user_id)
174
+
175
+ supabase.table("user_recommendations").upsert({
176
+ "user_id": user_id,
177
+ "recommended_trendz_ids": trendz,
178
+ "generated_at": datetime.now(timezone.utc).isoformat()
179
+ }).execute()
180
+
181
+ return {
182
+ "message": "✅ Trendz recommendations generated successfully",
183
+ "user_id": user_id,
184
+ "recommended_trendz": trendz
185
+ }
186
+ except Exception as e:
187
+ raise HTTPException(status_code=500, detail=str(e))