N4F1U commited on
Commit
09ac0b7
·
verified ·
1 Parent(s): 4063a35

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +112 -33
src/streamlit_app.py CHANGED
@@ -1,48 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # --- LOAD DATA FROM HUGGING FACE HUB ---
2
  @st.cache_resource
3
  def load_model_files():
4
- """Load model files from Hugging Face using direct URL download."""
5
  try:
6
- import requests
7
- import tempfile
8
-
9
- # Create temporary files
10
- with tempfile.NamedTemporaryFile(delete=False, suffix='.pkl') as tmp_movie:
11
- movie_temp_path = tmp_movie.name
12
 
13
- with tempfile.NamedTemporaryFile(delete=False, suffix='.pkl') as tmp_similarity:
14
- similarity_temp_path = tmp_similarity.name
 
 
 
 
15
 
16
- # Direct URLs to your files
17
- base_url = "https://huggingface.co/N4F1U/Movie_Recommender_tmdb/resolve/main/"
 
 
 
18
 
19
- # Download movie_list.pkl
20
- response = requests.get(base_url + "movie_list.pkl", stream=True)
21
- response.raise_for_status()
22
- with open(movie_temp_path, 'wb') as f:
23
- for chunk in response.iter_content(chunk_size=8192):
24
- f.write(chunk)
25
-
26
- # Download similarity.pkl
27
- response = requests.get(base_url + "similarity.pkl", stream=True)
28
- response.raise_for_status()
29
- with open(similarity_temp_path, 'wb') as f:
30
- for chunk in response.iter_content(chunk_size=8192):
31
- f.write(chunk)
32
-
33
- # Load the files
34
- with open(movie_temp_path, 'rb') as f:
35
  movies_data = pickle.load(f)
36
 
37
- with open(similarity_temp_path, 'rb') as f:
38
  similarity_data = pickle.load(f)
39
 
40
- # Clean up temporary files
41
- os.unlink(movie_temp_path)
42
- os.unlink(similarity_temp_path)
43
-
44
  return movies_data, similarity_data
45
 
46
  except Exception as e:
47
  st.error(f"Error loading model files: {e}")
48
- return None, None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pickle
2
+ import streamlit as st
3
+ import requests
4
+ from huggingface_hub import hf_hub_download
5
+ import os
6
+
7
+ # --- PAGE CONFIGURATION ---
8
+ st.set_page_config(
9
+ page_title="Movie Recommender",
10
+ page_icon="🎬",
11
+ layout="wide"
12
+ )
13
+
14
+ # --- STYLING ---
15
+ st.markdown("""
16
+ <style>
17
+ h1 { text-align: center; color: #FF4B4B; }
18
+ .movie-title { font-size: 16px; font-weight: bold; text-align: center; min-height: 3rem; color: #FFFFFF; }
19
+ .stButton > button { width: 100%; border-radius: 50px; font-size: 18px; font-weight: bold; margin: 0.5em 0; background-color: #FF4B4B; color: white; }
20
+ .stButton > button:hover { background-color: #FFFFFF; color: #FF4B4B; border: 2px solid #FF4B4B; }
21
+ </style>
22
+ """, unsafe_allow_html=True)
23
+
24
+ # --- API AND RECOMMENDATION FUNCTIONS ---
25
+ @st.cache_data
26
+ def fetch_poster(movie_id):
27
+ """Fetches the movie poster URL from TMDB API."""
28
+ url = f"https://api.themoviedb.org/3/movie/{movie_id}?api_key=8265bd1679663a7ea12ac168da84d2e8&language=en-US"
29
+ try:
30
+ response = requests.get(url)
31
+ response.raise_for_status()
32
+ data = response.json()
33
+ poster_path = data.get('poster_path')
34
+ if poster_path:
35
+ return "https://image.tmdb.org/t/p/w500/" + poster_path
36
+ else:
37
+ return "https://via.placeholder.com/500x750.png?text=No+Poster+Available"
38
+ except requests.exceptions.RequestException as e:
39
+ st.error(f"Error fetching data: {e}")
40
+ return "https://via.placeholder.com/500x750.png?text=API+Error"
41
+
42
+ def recommend(movie):
43
+ """Recommends 5 movies based on similarity."""
44
+ try:
45
+ index = movies[movies['title'] == movie].index[0]
46
+ distances = sorted(list(enumerate(similarity[index])), reverse=True, key=lambda x: x[1])
47
+
48
+ recommended_movie_names = []
49
+ recommended_movie_posters = []
50
+
51
+ for i in distances[1:6]:
52
+ movie_id = movies.iloc[i[0]].movie_id
53
+ recommended_movie_posters.append(fetch_poster(movie_id))
54
+ recommended_movie_names.append(movies.iloc[i[0]].title)
55
+
56
+ return recommended_movie_names, recommended_movie_posters
57
+ except IndexError:
58
+ st.error("Movie not found in the dataset. Please select another one.")
59
+ return [], []
60
+
61
  # --- LOAD DATA FROM HUGGING FACE HUB ---
62
  @st.cache_resource
63
  def load_model_files():
64
+ """Load model files from Hugging Face Hub with caching."""
65
  try:
66
+ # Set environment variable to use /tmp for cache
67
+ os.environ['HF_HOME'] = '/tmp/huggingface'
68
+ os.makedirs('/tmp/huggingface', exist_ok=True)
 
 
 
69
 
70
+ # Download files using Hugging Face Hub
71
+ movie_list_path = hf_hub_download(
72
+ repo_id="N4F1U/Movie_Recommender_tmdb",
73
+ filename="movie_list.pkl",
74
+ cache_dir="/tmp/huggingface"
75
+ )
76
 
77
+ similarity_path = hf_hub_download(
78
+ repo_id="N4F1U/Movie_Recommender_tmdb",
79
+ filename="similarity.pkl",
80
+ cache_dir="/tmp/huggingface"
81
+ )
82
 
83
+ # Load the pickle files
84
+ with open(movie_list_path, 'rb') as f:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  movies_data = pickle.load(f)
86
 
87
+ with open(similarity_path, 'rb') as f:
88
  similarity_data = pickle.load(f)
89
 
 
 
 
 
90
  return movies_data, similarity_data
91
 
92
  except Exception as e:
93
  st.error(f"Error loading model files: {e}")
94
+ st.error(f"Error type: {type(e).__name__}")
95
+ return None, None
96
+
97
+ # Load the data
98
+ movies, similarity = load_model_files()
99
+
100
+ if movies is None or similarity is None:
101
+ st.error("Failed to load model data. Please check your repository and try again.")
102
+ st.stop()
103
+
104
+ movie_list = movies['title'].values
105
+
106
+ # --- APP LAYOUT ---
107
+ st.title('Movie Recommender System 🍿')
108
+
109
+ # Center the selection box and button using columns
110
+ _, col_centered, _ = st.columns([1, 2, 1])
111
+ with col_centered:
112
+ selected_movie = st.selectbox(
113
+ "Type or select a movie to get recommendations",
114
+ movie_list
115
+ )
116
+
117
+ if st.button('Show Recommendation'):
118
+ with st.spinner('Finding similar movies for you...'):
119
+ recommended_names, recommended_posters = recommend(selected_movie)
120
+
121
+ if recommended_names:
122
+ st.success("Here are your top 5 recommendations!")
123
+ cols = st.columns(5, gap="medium")
124
+ for i, col in enumerate(cols):
125
+ with col:
126
+ st.markdown(f'<p class="movie-title">{recommended_names[i]}</p>', unsafe_allow_html=True)
127
+ st.image(recommended_posters[i], use_container_width='always')