Upload 5 files
Browse files- Dockerfile +26 -0
- app.py +41 -0
- imdb_top_1000/imdb_top_1000.csv +0 -0
- recommender.py +39 -0
- requirements.txt +2 -0
Dockerfile
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Use official Python image
|
2 |
+
FROM python:3.9-slim
|
3 |
+
|
4 |
+
# Set working directory
|
5 |
+
WORKDIR /app
|
6 |
+
|
7 |
+
# Install system dependencies
|
8 |
+
RUN apt-get update && apt-get install -y \
|
9 |
+
build-essential \
|
10 |
+
&& rm -rf /var/lib/apt/lists/*
|
11 |
+
|
12 |
+
# Copy project files into the container
|
13 |
+
COPY . /app
|
14 |
+
|
15 |
+
# Install Python dependencies
|
16 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
17 |
+
|
18 |
+
# Expose the port Streamlit uses
|
19 |
+
EXPOSE 7860
|
20 |
+
|
21 |
+
# Set the Streamlit app to run
|
22 |
+
ENV STREAMLIT_PORT=7860
|
23 |
+
ENV STREAMLIT_BROWSER_GATHER_USAGE_STATS=false
|
24 |
+
|
25 |
+
# Run Streamlit
|
26 |
+
CMD ["streamlit", "run", "app.py", "--server.port=7860", "--server.address=0.0.0.0"]
|
app.py
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
from recommender import load_movie_data, recommend_movies
|
4 |
+
|
5 |
+
# Load data
|
6 |
+
df = load_movie_data()
|
7 |
+
|
8 |
+
st.set_page_config(page_title="Movie Chatbot", layout="centered")
|
9 |
+
st.title("π¬ Movie Recommender Chatbot")
|
10 |
+
st.write("Answer a few quick questions and get personalized movie suggestions!")
|
11 |
+
|
12 |
+
# Step 1: Mood
|
13 |
+
mood = st.radio("What's your mood today?", ["Feel-good", "Intense", "Thought-provoking", "Funny"])
|
14 |
+
|
15 |
+
# Step 2: Genre
|
16 |
+
genre = st.selectbox("Pick a genre:", ["Any", "Sci-Fi", "Drama", "Romance", "Action", "Mystery", "Comedy", "Animation", "Thriller"])
|
17 |
+
|
18 |
+
# Step 3: Minimum rating
|
19 |
+
min_rating = st.slider("Minimum IMDb rating:", 1.0, 10.0, 7.0)
|
20 |
+
|
21 |
+
# Submit button
|
22 |
+
if st.button("π₯ Recommend Movies"):
|
23 |
+
st.write("Here are some movies you might like:")
|
24 |
+
|
25 |
+
results = recommend_movies(
|
26 |
+
df,
|
27 |
+
mood=None if mood == "Any" else mood,
|
28 |
+
genre=None if genre == "Any" else genre,
|
29 |
+
min_rating=min_rating
|
30 |
+
)
|
31 |
+
|
32 |
+
if not results.empty:
|
33 |
+
for _, row in results.iterrows():
|
34 |
+
if pd.notna(row["poster"]):
|
35 |
+
st.image(row["poster"], width=200)
|
36 |
+
|
37 |
+
st.markdown(f"**π¬ {row['title']}** ({row['year']}) β *{row['genre']}*")
|
38 |
+
st.write(f"β {row['rating']}")
|
39 |
+
st.markdown("---")
|
40 |
+
else:
|
41 |
+
st.warning("No movies matched your filters. Try relaxing the criteria!")
|
imdb_top_1000/imdb_top_1000.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
recommender.py
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
|
3 |
+
def load_movie_data(path="imdb_top_1000/imdb_top_1000.csv"):
|
4 |
+
df = pd.read_csv(path)
|
5 |
+
df.rename(columns={"Series_Title": "title", "Released_Year": "year", "Genre": "genre",
|
6 |
+
"IMDB_Rating": "rating", "Poster_Link": "poster"}, inplace=True)
|
7 |
+
|
8 |
+
# OPTIONAL: Add a fake 'mood' column based on genre (can be improved later)
|
9 |
+
df["mood"] = df["genre"].apply(lambda g: infer_mood_from_genre(g))
|
10 |
+
return df
|
11 |
+
|
12 |
+
def infer_mood_from_genre(genre_str):
|
13 |
+
genre_str = genre_str.lower() if isinstance(genre_str, str) else ""
|
14 |
+
if any(g in genre_str for g in ["romance", "comedy"]):
|
15 |
+
return "Feel-good"
|
16 |
+
elif any(g in genre_str for g in ["action", "thriller"]):
|
17 |
+
return "Intense"
|
18 |
+
elif "drama" in genre_str:
|
19 |
+
return "Thought-provoking"
|
20 |
+
elif "animation" in genre_str:
|
21 |
+
return "Funny"
|
22 |
+
else:
|
23 |
+
return "General"
|
24 |
+
|
25 |
+
def recommend_movies(df, mood=None, genre=None, min_rating=0.0):
|
26 |
+
filtered = df.copy()
|
27 |
+
|
28 |
+
if mood:
|
29 |
+
filtered = filtered[filtered["mood"].str.contains(mood, case=False, na=False)]
|
30 |
+
|
31 |
+
if genre and genre.lower() != "any":
|
32 |
+
filtered = filtered[filtered["genre"].str.contains(genre, case=False, na=False)]
|
33 |
+
|
34 |
+
filtered = filtered[filtered["rating"] >= min_rating]
|
35 |
+
|
36 |
+
filtered = filtered.sort_values(by="rating", ascending=False)
|
37 |
+
|
38 |
+
return filtered.head(10)
|
39 |
+
|
requirements.txt
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
streamlit
|
2 |
+
pandas
|