File size: 3,734 Bytes
f2ee240
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import asyncio
import os
import pickle

import aiohttp
import pandas as pd
import streamlit as st

from dotenv import load_dotenv

# Load the environment variable from .env file
load_dotenv()

# Configure page
st.set_page_config(
    page_title="Movie Recommender System",
    page_icon="🎬🍿",
    layout="wide"
)

# Cache the data loading
@st.cache_data
def load_data():
    with open("movies.pkl", "rb") as file:
        movies = pickle.load(file)
    movies = pd.DataFrame(movies)

    with open("similarity.pkl", "rb") as file:
        similarity = pickle.load(file)
    return movies, similarity

def my_api_key():
    api_key = os.environ["MOVIES_API_KEY"]
    if not api_key:
        st.error("API Key not found. Please check your .env file.")
        st.stop()
    return api_key

async def fetch_poster(session, movie_id):  
    url = f"https://api.themoviedb.org/3/movie/{movie_id}?api_key={my_api_key()}&language=en-US"
    try:
        async with session.get(url) as response:
            data = await response.json()
            poster_path = data.get("poster_path")
            if poster_path:
                return "https://image.tmdb.org/t/p/w500/" + poster_path
            return "https://via.placeholder.com/500x750?text=No+Poster+Available"
    except Exception as e:
        st.error(f"Error fetching poster for movie ID {movie_id}: {str(e)}")
        return "https://via.placeholder.com/500x750?text=Error+Loading+Poster"
    
async def get_recommendation(movie, movies, similarity):
    movie_index = movies[movies["title"] == movie].index[0]
    distances = similarity[movie_index]
    movies_list = sorted((enumerate(distances)), key=lambda x: x[1], reverse=True)

    async with aiohttp.ClientSession() as session:
        tasks = []
        recommended_movies_names = []
        for i in movies_list:
           movie_id = movies.loc[i[0]].movie_id
           recommended_movies_names.append(movies.loc[i[0]].title)
           tasks.append(fetch_poster(session, movie_id))

        recommended_movies_posters = await asyncio.gather(*tasks)
        return recommended_movies_names, recommended_movies_posters

def main():
    st.header("🎬🍿 Movie Recommender System")

    # Load Data
    with st.spinner("Loading movie data..."):
        movies, similarity = load_data()
        print(movies)
    
    # Create a sidebar for additional Information
    with st.sidebar:
        st.header("About")
        st.write("""

        This movie recommender system suggests similar movies based on your selection.

        It uses content-based filtering to make recommendations.

        """)
        st.metric("Total Movies", len(movies))

    # Main Content
    movies_list = movies["title"].values
    selected_movie_name = st.selectbox("Select a movie you like:",
    movies_list,
    help="Choose a movie to get similar recommendation")

    if st.button("Get Recommendations"):
        with st.spinner("Fetching recommendations..."):
            # Run async recommendation function
            recommended_movies_names, recommended_movies_posters = asyncio.run(get_recommendation(selected_movie_name, movies, similarity))
        # Display recommendations in a grid
        st.subheader("Recommended Movies")
        cols = st.columns(5)

        for index, (col, name, poster) in enumerate(zip(cols,
        recommended_movies_names, recommended_movies_posters)):
            with col:
                st.image(poster, caption=name, use_container_width=True)
                st.button("More Info", key=f"info_{index}", help=f"Click here to learn more")


if __name__ == "__main__":
    main()