N4F1U commited on
Commit
4063a35
·
verified ·
1 Parent(s): 7d5d60f

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +36 -113
src/streamlit_app.py CHANGED
@@ -1,125 +1,48 @@
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
- @st.cache_resource
64
  def load_model_files():
65
- """Load model files from Hugging Face Hub with caching."""
66
  try:
67
- from huggingface_hub import hf_hub_download
68
- import pickle
 
 
 
 
69
 
70
- # Download files directly to memory
71
- movie_list_bytes = hf_hub_download(
72
- repo_id="N4F1U/Movie_Recommender_tmdb",
73
- filename="movie_list.pkl",
74
- repo_type="model",
75
- local_dir_use_symlinks=False
76
- )
77
 
78
- similarity_bytes = hf_hub_download(
79
- repo_id="N4F1U/Movie_Recommender_tmdb",
80
- filename="similarity.pkl",
81
- repo_type="model",
82
- local_dir_use_symlinks=False
83
- )
84
 
85
- # Load from the downloaded file paths
86
- movies_data = pickle.load(open(movie_list_bytes, 'rb'))
87
- similarity_data = pickle.load(open(similarity_bytes, 'rb'))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
  return movies_data, similarity_data
90
 
91
  except Exception as e:
92
  st.error(f"Error loading model files: {e}")
93
- return None, None
94
-
95
- # Load the data
96
- movies, similarity = load_model_files()
97
-
98
- if movies is None or similarity is None:
99
- st.error("Failed to load model data. Please check your repository and try again.")
100
- st.stop()
101
-
102
- movie_list = movies['title'].values
103
-
104
- # --- APP LAYOUT ---
105
- st.title('Movie Recommender System 🍿')
106
-
107
- # Center the selection box and button using columns
108
- _, col_centered, _ = st.columns([1, 2, 1])
109
- with col_centered:
110
- selected_movie = st.selectbox(
111
- "Type or select a movie to get recommendations",
112
- movie_list
113
- )
114
-
115
- if st.button('Show Recommendation'):
116
- with st.spinner('Finding similar movies for you...'):
117
- recommended_names, recommended_posters = recommend(selected_movie)
118
-
119
- if recommended_names:
120
- st.success("Here are your top 5 recommendations!")
121
- cols = st.columns(5, gap="medium")
122
- for i, col in enumerate(cols):
123
- with col:
124
- st.markdown(f'<p class="movie-title">{recommended_names[i]}</p>', unsafe_allow_html=True)
125
- st.image(recommended_posters[i], use_container_width='always')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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