I am trying to build a system that curates music based on emotions or that is the idea for now, it was working perfectly fine for a while but suddenly whenever I want to retrieve recommendations based on emotions, I am getting a 404 status code error. I am really not able to pinpoint the problem
I'll share a few codes which is like the core concept, If I could get to know the exact solution to the problem or where the problem lies it would be helpful
Music.py
import requests
import random
from ai_ml.src.utils import get_spotify_access_token
from ai_ml.src.config import CONFIG
def get_music_recommendation(emotion, market=None):
try:
access_token = get_spotify_access_token()
except Exception as e:
print(f"Error retrieving access token: {e}")
return []
emotion_to_genre = {
"happy": [
"acoustic", "afrobeat", "alt-rock", "alternative", "ambient", "blues",
"bossa nova", "brazil", "chill", "classical", "club", "comedy", "dance",
"disco", "drum-and-bass", "edm", "electro", "electronic", "folk", "funk",
"garage", "gospel", "groove", "grunge", "happy", "house", "idm", "indie",
"indie-pop", "industrial", "j-dance", "j-idol", "j-pop", "j-rock", "jazz",
"k-pop", "kids", "latin", "latino", "pop", "pop-film", "post-dubstep",
"power-pop", "progressive-house", "reggae", "reggaeton", "rock", "rock-n-roll",
"salsa", "samba", "show-tunes", "singer-songwriter", "ska", "summer",
"swedish", "synth-pop", "tango", "techno", "trance", "world-music"
],
"sad": [
"blues", "classical", "emo", "folk", "indie-pop", "jazz", "latin", "latino",
"metalcore", "post-dubstep", "punk", "r-n-b", "rainy-day", "rock", "sad",
"singer-songwriter", "soul"
],
"angry": [
"black-metal", "death-metal", "grindcore", "hardcore", "heavy-metal",
"industrial", "metal", "metal-misc", "metalcore", "punk-rock", "punk"
],
"surprise": [
"anime", "electro", "experimental", "idm", "j-dance", "j-idol", "j-pop",
"j-rock", "post-dubstep", "psych-rock", "trip-hop", "turkish"
],
"neutral": [
"acoustic", "ambient", "chill", "classical", "country", "dancehall", "deep-house",
"detroit-techno", "dub", "dubstep", "edm", "electro", "electronic", "folk",
"french", "groove", "hard-rock", "honky-tonk", "house", "idm", "indie",
"indie-pop", "industrial", "j-pop", "kids", "latin", "mpb", "new-age",
"new-release", "opera", "party", "pop", "reggae", "reggaeton", "rockabilly",
"singer-songwriter", "soul", "soundtracks", "study", "synth-pop", "techno"
]
}
genre = emotion_to_genre.get(emotion.lower(), "pop")
headers = {
"Authorization": f"Bearer {access_token}"
}
available_markets = [
"AD", "AE", "AG", "AL", "AM", "AO", "AR", "AT", "AU", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI",
"BJ", "BN", "BO", "BR", "BS", "BT", "BW", "BY", "BZ", "CA", "CD", "CG", "CH", "CI", "CL", "CM", "CO", "CR",
"CV", "CW", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "ES", "ET", "FI", "FJ", "FM",
"FR", "GA", "GB", "GD", "GE", "GH", "GM", "GN", "GQ", "GR", "GT", "GW", "GY", "HK", "HN", "HR", "HT", "HU",
"ID", "IE", "IL", "IN", "IQ", "IS", "IT", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KR", "KW",
"KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MG", "MH",
"MK", "ML", "MN", "MO", "MR", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NE", "NG", "NI", "NL", "NO",
"NP", "NR", "NZ", "OM", "PA", "PE", "PG", "PH", "PK", "PL", "PR", "PS", "PT", "PW", "PY", "QA", "RO", "RS",
"RW", "SA", "SB", "SC", "SE", "SG", "SI", "SK", "SL", "SM", "SN", "SR", "ST", "SV", "SZ", "TD", "TG", "TH",
"TJ", "TL", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "US", "UY", "UZ", "VC", "VE", "VN", "VU",
"WS", "XK", "ZA", "ZM", "ZW"
]
selected_market = market if market in available_markets else random.choice(available_markets)
params = {
"seed_genres": genre,
"limit": 25,
"market": selected_market
}
if emotion == "happy":
params["target_valence"] = 0.8
params["target_energy"] = 0.7
elif emotion == "sad":
params["target_valence"] = 0.2
params["target_energy"] = 0.2
elif emotion == "angry":
params["target_valence"] = 0.2
params["target_energy"] = 0.9
elif emotion == "surprise":
params["target_valence"] = 0.6
params["target_energy"] = 0.8
else:
params["target_valence"] = 0.5
params["target_energy"] = 0.5
response = requests.get("https://api.spotify.com/v1/recommendations", headers=headers, params=params)
if response.status_code == 401:
print("Access token expired. Please refresh the token.")
return []
elif response.status_code != 200:
print(f"Failed to fetch music recommendations. Status code: {response.status_code}")
return []
tracks = response.json().get("tracks", [])
recommended_tracks = [
{
"name": track["name"],
"artist": ", ".join([artist["name"] for artist in track["artists"]]),
"preview_url": track.get("preview_url"),
"external_url": track.get("external_urls", {}).get("spotify"),
"image_url": next((img["url"] for img in track["album"]["images"]), None),
"album_name": track["album"]["name"],
"release_date": track["album"].get("release_date"),
"track_duration": track.get("duration_ms") // 1000 if track.get("duration_ms") else None,
"popularity": track.get("popularity"),
"explicit": track.get("explicit"),
}
for track in tracks
]
if not recommended_tracks:
print(f"No tracks found for genre: {genre}")
return recommended_tracks`
utils.py
import base64
import requests
from ai_ml.src.config import CONFIG
def get_spotify_access_token():
client_id = CONFIG["spotify_client_id"]
client_secret = CONFIG["spotify_client_secret"]
token_url = "https://accounts.spotify.com/api/token"
# Create the authorization header
auth_header = base64.b64encode(f"{client_id}:{client_secret}".encode()).decode()
headers = {
"Authorization": f"Basic {auth_header}"
}
data = {
"grant_type": "client_credentials"
}
response = requests.post(token_url, headers=headers, data=data)
if response.status_code != 200:
raise Exception("Failed to retrieve Spotify access token")
return response.json().get("access_token")
config is a separate python script with my client and client_secret id
This is because the API was deprecated on November 27, 2024.