IshmamF commited on
Commit
16568c6
1 Parent(s): 03295d1

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +187 -0
app.py ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import numpy as np
3
+ import pandas as pd
4
+ import tensorflow as tf
5
+ from transformers import RobertaTokenizer, TFRobertaForSequenceClassification
6
+ from sentence_transformers import SentenceTransformer, util
7
+ import spotipy
8
+ from spotipy.oauth2 import SpotifyClientCredentials
9
+
10
+ sim_model = SentenceTransformer("sentence-transformers/all-mpnet-base-v2")
11
+
12
+ # Function to analyze sentiment of the user's input
13
+ def analyze_user_input(user_input, tokenizer, model):
14
+ encoded_input = tokenizer(user_input, return_tensors="tf", truncation=True, padding=True, max_length=512)
15
+ outputs = model(encoded_input)
16
+ scores = tf.nn.softmax(outputs.logits, axis=-1).numpy()[0]
17
+ predicted_class_idx = tf.argmax(outputs.logits, axis=-1).numpy()[0]
18
+ sentiment_label = model.config.id2label[predicted_class_idx]
19
+ sentiment_score = scores[predicted_class_idx]
20
+ return sentiment_label, sentiment_score
21
+
22
+ # Function to match songs from the dataset with the user's sentiment
23
+ def match_songs_with_sentiment(user_sentiment_label, user_sentiment_score,inputVector, score_range,songs_df):
24
+
25
+ # Filter songs with the same sentiment label
26
+ matched_songs = songs_df[songs_df['sentiment'] == user_sentiment_label]
27
+
28
+ # Calculate the score range
29
+ score_min = max(0, user_sentiment_score - score_range)
30
+ score_max = min(1, user_sentiment_score + score_range)
31
+
32
+ # Further filter songs whose scores fall within the specified range
33
+ matched_songs = matched_songs[(matched_songs['score'] >= score_min) & (matched_songs['score'] <= score_max)]
34
+
35
+ # Shuffle the matched songs to get a random order
36
+ matched_songs = matched_songs.sample(frac=1).reset_index(drop=True)
37
+
38
+ matched_songs['similarity'] = matched_songs['seq'].apply(lambda x: util.pytorch_cos_sim(sim_model.encode(x), inputVector))
39
+
40
+ top_5 = matched_songs['similarity'].sort_values(ascending=False).head(5)
41
+
42
+ # Sort the songs by how close their score is to the user's sentiment score
43
+ # matched_songs['score_diff'] = abs(matched_songs['score'] - user_sentiment_score)
44
+ # matched_songs = matched_songs.sort_values(by='score_diff')
45
+
46
+ # Select the top five songs and return
47
+ return matched_songs.loc[top_5.index, ['song','artist','seq','similarity','sentiment','score']]
48
+
49
+ client_id = 'c34955a27b6447e3a1b92305d04bbbea'
50
+ client_secret = '1d197925c0654b5da80bd3cfa1f5afdd'
51
+
52
+ client_credentials_manager = SpotifyClientCredentials(client_id=client_id, client_secret=client_secret)
53
+ sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
54
+
55
+ def get_track_id(song_name):
56
+ # Search for the track ID using the song name
57
+ results = sp.search(q=song_name, type='track', limit=1)
58
+ if results['tracks']['items']:
59
+ track_id = results['tracks']['items'][0]['id']
60
+ return track_id
61
+ else:
62
+ print(f"No results found for {song_name}")
63
+ return None
64
+
65
+ def get_track_preview_url(track_id):
66
+ # Get the 30-second preview URL for the track
67
+ track_info = sp.track(track_id)
68
+ preview_url = track_info['preview_url']
69
+ return preview_url
70
+
71
+ # Initialize the tokenizer and model outside of the functions to speed up repeated calls
72
+ tokenizer = RobertaTokenizer.from_pretrained('roberta-base')
73
+ model = TFRobertaForSequenceClassification.from_pretrained('arpanghoshal/EmoRoBERTa')
74
+
75
+ # Streamlit app layout
76
+ st.set_page_config(page_title="MODUS MUSIC", layout="wide") # New: Setting page title and layout
77
+
78
+ # Custom CSS for background and text color
79
+ st.markdown("""
80
+ <style>
81
+ .stApp {
82
+ background: rgb(0,0,0);
83
+ background-size: cover;
84
+ color: white; /* Sets global text color to white */
85
+ }
86
+ /* General rule for all labels */
87
+ label {
88
+ color: white !important;
89
+ }
90
+ /* Specific color for the main title */
91
+ h1 {
92
+ color: red !important; /* Making the MODUS MUSIC title red */
93
+ }
94
+ /* Additional specific styling */
95
+ .stTextInput > label, .stButton > button, .css-10trblm, .css-1yjuwjr, .intro {
96
+ color: white !important;
97
+ }
98
+ </style>
99
+ """, unsafe_allow_html=True)
100
+
101
+
102
+ image_path = '/content/MODUSMUSIC.png' # Replace with the actual path to your image
103
+
104
+ st.image(image_path, use_column_width=False, width=250) # Adjust the width as needed
105
+ # Custom gradient background using CSS
106
+ st.markdown("""
107
+ <style>
108
+ .stApp {
109
+ background: rgb(0,0,0);
110
+ background-size: cover;
111
+ }
112
+ </style>
113
+ """, unsafe_allow_html=True)
114
+
115
+ # Custom HTML for the main title
116
+ st.markdown("<h1 style='text-align: center; font-weight: bold;'>MODUS MUSIC</h1>", unsafe_allow_html=True)
117
+
118
+ st.title('Music Suggestion Based on Your Feeling') # Existing Title
119
+
120
+ # New: Introduction Section
121
+ with st.container():
122
+ st.markdown("""
123
+ <style>
124
+ .intro {
125
+ font-size:18px;
126
+ }
127
+ </style>
128
+ <div class='intro'>
129
+ Welcome to Modus Music! Share your vibe, and let's find the perfect songs to match your mood.
130
+ Just type in your thoughts, and we'll do the rest.
131
+ </div>
132
+ """, unsafe_allow_html=True)
133
+
134
+ # User input text area
135
+ with st.container():
136
+ user_input = st.text_area("What's your vibe? Tell me about it:", key="123", height=150, max_chars=500)
137
+ m = st.markdown("""
138
+ <style>
139
+ div.stButton > button:first-child {
140
+ background-color: rgb(204, 49, 49);
141
+
142
+ }
143
+ </style>""", unsafe_allow_html=True)
144
+ # Use the custom style for the button
145
+ submit_button = st.button("Generate music")
146
+
147
+
148
+ # Processing and Displaying Results
149
+ if submit_button and len(user_input.split()) > 5:
150
+ # New: Define inputVector here
151
+ inputVector = sim_model.encode(user_input)
152
+
153
+ # Run sentiment analysis on the user input
154
+ sentiment_label, sentiment_score = analyze_user_input(user_input, tokenizer, model)
155
+ st.write(f"Sentiment: {sentiment_label}, Score: {sentiment_score:.2f}")
156
+
157
+ # Load songs dataframe
158
+ songs_df = pd.read_csv('/content/music_mental_health.csv')
159
+
160
+ # Suggest songs
161
+ suggested_songs = match_songs_with_sentiment(sentiment_label, sentiment_score, inputVector, 0.00625, songs_df)
162
+ suggested_songs['similarity'] = suggested_songs['similarity'].apply(lambda x: x.numpy()[0][0])
163
+
164
+ # Styling for the suggested songs display
165
+ with st.container():
166
+ st.markdown("<div class='song-list'>", unsafe_allow_html=True)
167
+ st.write("Based on your vibe, you might like these songs:")
168
+ for index, row in suggested_songs.iterrows():
169
+ song = row['song']
170
+ artist = row['artist']
171
+ track_id = get_track_id(song)
172
+ if track_id.strip():
173
+ preview_url = get_track_preview_url(track_id)
174
+ #st.write(f"Similarity: {row['similarity']}")
175
+ st.write(f"{song} by {artist}")
176
+ with st.expander(f"Show Lyrics for {song} by {artist}", expanded=False):
177
+ st.write(f"Lyrics: {row['seq']}")
178
+
179
+ if preview_url:
180
+ st.audio(preview_url)
181
+ else:
182
+ st.write("No Preview Available")
183
+ st.markdown("</div>", unsafe_allow_html=True)
184
+ st.dataframe(suggested_songs[['song','artist','seq','similarity','sentiment','score']])
185
+ elif submit_button and not len(user_input.split()) > 5:
186
+ st.warning("Please provide a longer response with 5 words or more.")
187
+ st.rerun()