hfariborzi commited on
Commit
ff74c4e
ยท
verified ยท
1 Parent(s): 8bc4469

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +177 -46
app.py CHANGED
@@ -1,51 +1,182 @@
 
 
 
 
 
 
1
  import streamlit as st
2
- import google.generativeai as genai
3
- import os
4
-
5
- # Securely retrieve API key from environment variables
6
- GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
7
-
8
- # Ensure the API key is set before configuring Gemini
9
- if GOOGLE_API_KEY:
10
- genai.configure(api_key=GOOGLE_API_KEY)
11
- else:
12
- st.error("โŒ API Key is missing! Please set it in Hugging Face Secrets.")
13
-
14
- # Function to generate a funny story
15
- def get_funny_story(query, style, length):
16
- prompt = (
17
- f"Write a funny short story based on this query: '{query}'. "
18
- f"Make it {length} sentences long and style it as {style}. "
19
- "The story should be humorous and entertaining."
20
- )
21
-
22
- try:
23
- model = genai.GenerativeModel("gemini-2.0-pro-exp-02-05")
24
- response = model.generate_content(prompt)
25
- return response.text
26
- except Exception as e:
27
- return f"Error generating story: {e}"
28
-
29
- # Streamlit UI
30
- st.title("๐Ÿ˜‚ Funny Story Generator")
31
-
32
- # User Input: Query
33
- query = st.text_input("Enter a topic or query for your funny story:")
34
-
35
- # User Input: Story Style (Dropdown)
36
- style = st.selectbox(
37
- "Select a storytelling style:",
38
- ["Witty and Sarcastic", "Goofy and Childish", "Epic and Dramatic", "Absurd and Nonsensical"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  )
40
 
41
- # User Input: Story Length (Slider)
42
- length = st.slider("Select story length (in sentences)", min_value=3, max_value=15, value=7)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
- # Generate Story Button
45
- if st.button("Generate Funny Story"):
46
- if query.strip():
47
- story = get_funny_story(query, style, length)
48
- st.subheader("๐Ÿ“– Your Funny Story:")
49
- st.write(story)
50
  else:
51
- st.warning("Please enter a query for your story.")
 
1
+ import requests
2
+ import pandas as pd
3
+ import spacy
4
+ from sklearn.feature_extraction.text import TfidfVectorizer
5
+ from sklearn.metrics.pairwise import cosine_similarity
6
+ from textblob import TextBlob
7
  import streamlit as st
8
+
9
+ # ๐Ÿ”น Replace this with your TMDB API Key
10
+ API_KEY = "bbb69cf69be036e363d9ab8996f7f4ee"
11
+ BASE_URL = "https://api.themoviedb.org/3"
12
+
13
+ # ๐Ÿ”น TMDB Image Base URL for posters
14
+ IMAGE_BASE_URL = "https://image.tmdb.org/t/p/w500"
15
+
16
+ # Load Spacy English NLP model
17
+ nlp = spacy.load("en_core_web_sm")
18
+
19
+
20
+ # ===========================
21
+ # STEP 1: FETCH MOVIE DATA
22
+ # ===========================
23
+ def fetch_movies(num_pages=2):
24
+ """Fetch popular movies from TMDB API."""
25
+ all_movies = []
26
+
27
+ for page in range(1, num_pages + 1):
28
+ url = f"{BASE_URL}/discover/movie?api_key={API_KEY}&language=en-US&sort_by=popularity.desc&page={page}"
29
+ response = requests.get(url)
30
+ data = response.json()
31
+
32
+ if "results" in data:
33
+ for movie in data["results"]:
34
+ all_movies.append({
35
+ "id": movie["id"],
36
+ "title": movie["title"],
37
+ "overview": movie["overview"],
38
+ "vote_average": movie["vote_average"],
39
+ "release_date": movie["release_date"]
40
+ })
41
+
42
+ return pd.DataFrame(all_movies)
43
+
44
+
45
+ # ===========================
46
+ # STEP 2: FETCH ADDITIONAL DETAILS (GENRES, CAST, DIRECTOR)
47
+ # ===========================
48
+ def fetch_genres():
49
+ """Retrieve genre names from TMDB API and return a dictionary mapping genre IDs to names."""
50
+ url = f"{BASE_URL}/genre/movie/list?api_key={API_KEY}&language=en-US"
51
+ response = requests.get(url)
52
+ data = response.json()
53
+
54
+ return {genre["id"]: genre["name"] for genre in data["genres"]}
55
+
56
+
57
+ def fetch_movie_details(movie_id):
58
+ """Fetch top 3 cast members and director for a given movie."""
59
+ url = f"{BASE_URL}/movie/{movie_id}/credits?api_key={API_KEY}"
60
+ response = requests.get(url)
61
+ data = requests.get(url).json()
62
+
63
+ # Get top 3 cast members
64
+ cast = ", ".join([member["name"] for member in data.get("cast", [])[:3]])
65
+
66
+ # Get director
67
+ director = next((crew["name"] for crew in data.get("crew", []) if crew["job"] == "Director"), "Unknown")
68
+
69
+ return cast, director
70
+
71
+
72
+ # ===========================
73
+ # STEP 3: ENRICH MOVIE DATA WITH GENRES, CAST, DIRECTOR
74
+ # ===========================
75
+ def enhance_movie_data(movies_df):
76
+ """Add genres, top cast, and director information to the movie dataset."""
77
+ genre_dict = fetch_genres()
78
+
79
+ movies_df["cast"], movies_df["director"] = zip(*movies_df["id"].apply(fetch_movie_details))
80
+ return movies_df
81
+
82
+
83
+ # ===========================
84
+ # STEP 4: FEATURE ENGINEERING (KEYWORDS & SENTIMENT)
85
+ # ===========================
86
+ def extract_keywords(text, num_keywords=5):
87
+ """Extract top keywords from text using TF-IDF."""
88
+ vectorizer = TfidfVectorizer(stop_words="english", max_features=50)
89
+ tfidf_matrix = vectorizer.fit_transform([text])
90
+ feature_names = vectorizer.get_feature_names_out()
91
+
92
+ sorted_indices = tfidf_matrix.toarray().argsort()[0][-num_keywords:]
93
+ return ", ".join(feature_names[i] for i in sorted_indices)
94
+
95
+
96
+ def get_sentiment(text):
97
+ """Analyze sentiment (-1 to 1) from movie description using TextBlob."""
98
+ return TextBlob(text).sentiment.polarity
99
+
100
+
101
+ # ===========================
102
+ # STEP 5: BUILD RECOMMENDER SYSTEM (CONTENT-BASED FILTERING)
103
+ # ===========================
104
+ def recommend_movies(movie_title, num_recommendations=5):
105
+ """Recommend similar movies based on content similarity."""
106
+ if movie_title not in movies_df["title"].values:
107
+ return "Movie not found in dataset!"
108
+
109
+ # Get index of the selected movie
110
+ movie_index = movies_df[movies_df["title"] == movie_title].index[0]
111
+
112
+ # Compute similarity scores and sort them
113
+ similarity_scores = list(enumerate(cosine_sim[movie_index]))
114
+ similarity_scores = sorted(similarity_scores, key=lambda x: x[1], reverse=True)[1:num_recommendations + 1]
115
+
116
+ # Get recommended movie titles
117
+ return [movies_df.iloc[i[0]]["title"] for i in similarity_scores]
118
+
119
+
120
+ # ===========================
121
+ # STEP 6: FETCH MOVIE POSTER
122
+ # ===========================
123
+ def get_movie_poster(movie_title):
124
+ """Fetch movie poster from TMDB API."""
125
+ movie = movies_df[movies_df["title"] == movie_title]
126
+ if not movie.empty:
127
+ movie_id = movie.iloc[0]["id"]
128
+ url = f"https://api.themoviedb.org/3/movie/{movie_id}?api_key={API_KEY}"
129
+ response = requests.get(url).json()
130
+ return IMAGE_BASE_URL + response.get("poster_path", "")
131
+ return None
132
+
133
+
134
+ # ===========================
135
+ # STEP 7: LOAD & PROCESS MOVIE DATA
136
+ # ===========================
137
+ movies_df = fetch_movies(num_pages=2) # Fetch movie data
138
+ movies_df = enhance_movie_data(movies_df) # Add cast, director info
139
+
140
+ # Apply feature extraction
141
+ movies_df["keywords"] = movies_df["overview"].apply(lambda x: extract_keywords(str(x)))
142
+ movies_df["sentiment"] = movies_df["overview"].apply(lambda x: get_sentiment(str(x)))
143
+
144
+ # Combine relevant text features for recommendation
145
+ movies_df["combined_features"] = (
146
+ movies_df["overview"].fillna("") + " " +
147
+ movies_df["keywords"].fillna("")
148
  )
149
 
150
+ # Convert text into numerical vectors using TF-IDF
151
+ tfidf_vectorizer = TfidfVectorizer(stop_words="english")
152
+ tfidf_matrix = tfidf_vectorizer.fit_transform(movies_df["combined_features"])
153
+
154
+ # Compute similarity scores between movies
155
+ cosine_sim = cosine_similarity(tfidf_matrix, tfidf_matrix)
156
+
157
+ # ===========================
158
+ # STEP 8: STREAMLIT APP UI
159
+ # ===========================
160
+ st.title("๐ŸŽฌ Movie Recommendation System")
161
+
162
+ # Dropdown to select a movie
163
+ selected_movie = st.selectbox("Select a Movie", movies_df["title"].values)
164
+
165
+ # Recommend button
166
+ if st.button("Recommend"):
167
+ recommendations = recommend_movies(selected_movie)
168
+
169
+ if isinstance(recommendations, list):
170
+ st.subheader(f"Movies similar to {selected_movie}:")
171
+
172
+ # Display recommended movies in a horizontal layout
173
+ cols = st.columns(len(recommendations))
174
 
175
+ for i, movie in enumerate(recommendations):
176
+ poster_url = get_movie_poster(movie)
177
+ with cols[i]:
178
+ if poster_url:
179
+ st.image(poster_url, width=150)
180
+ st.write(f"**{movie}**")
181
  else:
182
+ st.error("No recommendations found.")