Spaces:
Sleeping
Sleeping
Update src/streamlit_app.py
Browse files- src/streamlit_app.py +1 -67
src/streamlit_app.py
CHANGED
|
@@ -3,10 +3,6 @@ import requests
|
|
| 3 |
import pandas as pd
|
| 4 |
from together import Together
|
| 5 |
import os
|
| 6 |
-
import numpy as np
|
| 7 |
-
from sentence_transformers import SentenceTransformer
|
| 8 |
-
from sklearn.metrics.pairwise import cosine_similarity
|
| 9 |
-
import pickle
|
| 10 |
|
| 11 |
# =============================================================================
|
| 12 |
# CONFIGURATION - Using Secrets Management
|
|
@@ -235,51 +231,6 @@ def extract_unique_names(content_list, field):
|
|
| 235 |
unique_names.add(cleaned_name)
|
| 236 |
return sorted(list(unique_names))
|
| 237 |
|
| 238 |
-
def generate_content_embeddings(content_list, model_name='all-MiniLM-L6-v2'):
|
| 239 |
-
"""Generate embeddings for content using sentence transformers"""
|
| 240 |
-
# Check if embeddings already exist
|
| 241 |
-
if os.path.exists('content_embeddings.pkl'):
|
| 242 |
-
with open('content_embeddings.pkl', 'rb') as f:
|
| 243 |
-
return pickle.load(f)
|
| 244 |
-
|
| 245 |
-
# Initialize the model
|
| 246 |
-
model = SentenceTransformer(model_name)
|
| 247 |
-
|
| 248 |
-
# Prepare content descriptions
|
| 249 |
-
descriptions = []
|
| 250 |
-
for content in content_list:
|
| 251 |
-
# Combine relevant text fields for better embedding
|
| 252 |
-
text = f"{content.get('title', '')} {content.get('description', '')} {content.get('listed_in', '')} {content.get('cast', '')} {content.get('director', '')}"
|
| 253 |
-
descriptions.append(text)
|
| 254 |
-
|
| 255 |
-
# Generate embeddings
|
| 256 |
-
embeddings = model.encode(descriptions, show_progress_bar=True)
|
| 257 |
-
|
| 258 |
-
# Save embeddings
|
| 259 |
-
with open('content_embeddings.pkl', 'wb') as f:
|
| 260 |
-
pickle.dump(embeddings, f)
|
| 261 |
-
|
| 262 |
-
return embeddings
|
| 263 |
-
|
| 264 |
-
def get_content_recommendations(content_list, selected_content_idx, embeddings, n_recommendations=5):
|
| 265 |
-
"""Get content recommendations based on similarity"""
|
| 266 |
-
# Calculate similarity scores
|
| 267 |
-
similarity_scores = cosine_similarity([embeddings[selected_content_idx]], embeddings)[0]
|
| 268 |
-
|
| 269 |
-
# Get indices of top similar items (excluding self)
|
| 270 |
-
similar_indices = similarity_scores.argsort()[::-1][1:n_recommendations+1]
|
| 271 |
-
|
| 272 |
-
# Get similarity scores for recommended items
|
| 273 |
-
scores = similarity_scores[similar_indices]
|
| 274 |
-
|
| 275 |
-
# Get recommended content items with their similarity scores
|
| 276 |
-
recommendations = [
|
| 277 |
-
(content_list[idx], score)
|
| 278 |
-
for idx, score in zip(similar_indices, scores)
|
| 279 |
-
]
|
| 280 |
-
|
| 281 |
-
return recommendations
|
| 282 |
-
|
| 283 |
# =============================================================================
|
| 284 |
# MAIN APP
|
| 285 |
# =============================================================================
|
|
@@ -325,10 +276,6 @@ def main():
|
|
| 325 |
st.error("Could not load Netflix content. Please check your NocoDB connection.")
|
| 326 |
st.stop()
|
| 327 |
|
| 328 |
-
# Generate content embeddings
|
| 329 |
-
with st.spinner("Generating content embeddings (this may take a while the first time)..."):
|
| 330 |
-
embeddings = generate_content_embeddings(all_content)
|
| 331 |
-
|
| 332 |
# Extract unique values for filters
|
| 333 |
all_ratings = sorted(list(set([c.get('rating') for c in all_content if c.get('rating')])))
|
| 334 |
all_genres = sorted(list(set(
|
|
@@ -466,7 +413,7 @@ def main():
|
|
| 466 |
st.write(f"- Cast: {filters['cast']}")
|
| 467 |
st.write("---")
|
| 468 |
|
| 469 |
-
# Show first 10 items
|
| 470 |
for i, content in enumerate(st.session_state.filtered_content[:10]):
|
| 471 |
with st.expander(f"{content.get('title', 'N/A')} ({content.get('release_year', 'N/A')})"):
|
| 472 |
# Content details in columns
|
|
@@ -487,19 +434,6 @@ def main():
|
|
| 487 |
# Description
|
| 488 |
st.write(f"**π Description:**")
|
| 489 |
st.write(content.get('description', 'N/A'))
|
| 490 |
-
|
| 491 |
-
# Find content index in original list for recommendations
|
| 492 |
-
try:
|
| 493 |
-
content_idx = all_content.index(content)
|
| 494 |
-
if st.button(f"π― Get Similar Content", key=f"rec_{i}"):
|
| 495 |
-
recommendations = get_content_recommendations(all_content, content_idx, embeddings)
|
| 496 |
-
st.write("**π¬ Similar Content You Might Like:**")
|
| 497 |
-
for rec, score in recommendations:
|
| 498 |
-
score_percentage = int(score * 100)
|
| 499 |
-
st.write(f"- **{rec.get('title')}** ({rec.get('release_year')}) - {score_percentage}% match")
|
| 500 |
-
st.write(f" *{rec.get('type')} | {rec.get('listed_in')}*")
|
| 501 |
-
except ValueError:
|
| 502 |
-
st.error("Unable to generate recommendations for this title.")
|
| 503 |
|
| 504 |
if filtered_count > 10:
|
| 505 |
st.info(f"Showing first 10 of {filtered_count:,} titles. Adjust filters to narrow results.")
|
|
|
|
| 3 |
import pandas as pd
|
| 4 |
from together import Together
|
| 5 |
import os
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
# =============================================================================
|
| 8 |
# CONFIGURATION - Using Secrets Management
|
|
|
|
| 231 |
unique_names.add(cleaned_name)
|
| 232 |
return sorted(list(unique_names))
|
| 233 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 234 |
# =============================================================================
|
| 235 |
# MAIN APP
|
| 236 |
# =============================================================================
|
|
|
|
| 276 |
st.error("Could not load Netflix content. Please check your NocoDB connection.")
|
| 277 |
st.stop()
|
| 278 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 279 |
# Extract unique values for filters
|
| 280 |
all_ratings = sorted(list(set([c.get('rating') for c in all_content if c.get('rating')])))
|
| 281 |
all_genres = sorted(list(set(
|
|
|
|
| 413 |
st.write(f"- Cast: {filters['cast']}")
|
| 414 |
st.write("---")
|
| 415 |
|
| 416 |
+
# Show first 10 items
|
| 417 |
for i, content in enumerate(st.session_state.filtered_content[:10]):
|
| 418 |
with st.expander(f"{content.get('title', 'N/A')} ({content.get('release_year', 'N/A')})"):
|
| 419 |
# Content details in columns
|
|
|
|
| 434 |
# Description
|
| 435 |
st.write(f"**π Description:**")
|
| 436 |
st.write(content.get('description', 'N/A'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 437 |
|
| 438 |
if filtered_count > 10:
|
| 439 |
st.info(f"Showing first 10 of {filtered_count:,} titles. Adjust filters to narrow results.")
|