# Streamlit application # Import necessary libraries import streamlit as st import pandas as pd from openai import OpenAI from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity # Import data music_data = pd.read_csv("Spotify_Youtube.csv") # Specify api key for OpenAIs API client = OpenAI(api_key="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") # Function that calls OpenAIs API def parse_user_input(user_input): response = client.chat.completions.create( model="gpt-3.5-turbo", messages=[ { "role": "system", "content": """You will be provided with an input: '{user_input}', and your task is to determine the following: - Valence: a number that is equal to the mood. Positive moods are closer to 1 and negative moods are closer to 0. - Number of songs: the number of songs the user requests. - Tempo: the tempo of the songs. - Danceability: the danceability of the songs. Provide this information in the following format with each value separated by a space: 'valence number_of_songs tempo danceability' Example: '0.5 20 120 0.8' """ }, { "role": "user", "content": user_input }, { "role": "assistant", "content": "0.5 20, 120, 0.8" } ], temperature=0.5, max_tokens=64, top_p=1 ) return response.choices[0].message.content # Function create new dataframe from music dataframe based on valence, number of tracks, tempo an danceability def get_tracks_by_artist_and_danceability(music_data, valence, num_tracks, tempo, danceability): filtered_tracks = music_data[ (music_data['Valence'].between(valence - 0.1, valence + 0.1)) & (music_data['Tempo'].between(tempo - 30, tempo + 30)) & (music_data['Danceability'].between(danceability - 0.2, danceability + 0.2)) ] return filtered_tracks.head(num_tracks)[['Track', 'Artist']] # Function the recommends tracks by using tfidVectoricer and cosine_similarities def recommend_tracks(track_names, track_ids, top_k=20): vectorizer = TfidfVectorizer() tfidf_matrix = vectorizer.fit_transform(track_names) similarities = cosine_similarity(tfidf_matrix) avg_similarity = similarities.mean(axis=0) top_indices = avg_similarity.argsort()[-top_k:][::-1] return track_ids.iloc[top_indices] # Streamlit Application logo = "music_logo.png" # Sidebar with st.sidebar: st.image(logo, width=100) st.header("Navigation") tab_selection = st.sidebar.radio("Go to", ["Music Generator", "Browse Music", "About Us"]) # Music generator page if tab_selection == "Music Generator": st.header("Mood Playlist Generator", divider='rainbow') st.write("Enter your music preferences in a detailed format and recieve a personalized playlist based on your mood:") user_prompt = st.text_input("Example: 'I want 20 happy songs with a lot of tempo that i can dance to!'") if st.button("Generate Playlist"): try: with st.spinner("Processing your request..."): parsed_input = parse_user_input(user_prompt) #st.write(f"Parsed input: {parsed_input}") # Extract valence and number of songs from the parsed input valence, num_tracks, tempo, danceability = parsed_input.split() valence = float(valence) num_tracks = int(num_tracks) tempo = int(tempo) danceability = (float(danceability)) #st.write(f"Number of tracks: {num_tracks}, Valence: {valence}, Tempo: {tempo}, Danceability: {danceability}") tracks = get_tracks_by_artist_and_danceability(music_data, valence, num_tracks, tempo, danceability) #st.write(f"Found {len(tracks)} tracks.") if tracks.empty: st.write("No tracks found. Please try a different query.") else: track_names = tracks['Track'].tolist() track_ids = tracks[['Track', 'Artist']] #st.write("Track names:", track_names) recommended_tracks = recommend_tracks(track_names, track_ids, top_k=int(num_tracks)) st.write("Here are your recommended playlist:") st.table(recommended_tracks) st.button("Add playlist to Spotify") except ValueError: st.write("Error: Unable to parse the input. Please make sure the format is correct.") # Browse music page elif tab_selection == "Browse Music": st.header("Browse Music", divider='rainbow') st.write("Explore the music data used for generating your playlists.") df = pd.read_csv("Spotify_Youtube.csv") st.dataframe(df) # About us page elif tab_selection == "About Us": st.header("About Us", divider='rainbow') st.write(""" This App is developed by 4 ambitious university students, whose goals are to create playlists and music experiences which you can emotionally connect with. """) st.image("group_photo.jpg", caption="Our Team", use_column_width=True) # Add custom CSS st.markdown( """ """, unsafe_allow_html=True )