Я создаю систему рекомендаций Spotify, используя колбу и Spotipy. У меня есть функция, в которой система может генерировать 20 рекомендаций по песням на основе артистов, которые пользователь ввел в форму HTML. Все могло бежать неделю назад без ошибок. Однако, когда я продолжал работать над этой системой в последние несколько дней, я получал SpotifyException и не смог пройти ее. Я не внес никаких изменений в свой код с того дня, как он работал.
HTTP Error for GET to https://api.spotify.com/v1/audio-features/?ids=1BxfuPKGuaTgP7aM0Bbdwr,2OzhQlSqBEmt7hmkYxfT6m,4q5YezDOIPcoLr8R81x9qy,3hUxzQpSfdDqwM3ZTFQY0K,4R2kfaDFhslZEMJqAFNpdd,1dGr1c8CrMLDpV6mPbImSI,1R0a2iXumgCiFb7HEZ7gUE,0V3wPSX9ygBnCm8psDIegu,1u8c2t2Cy7UBoG4ArRcF5g,0W0iAC1VGlB82PI6elxFYf with Params: {} returned 403 due to None
{
"error": {
"status": 401,
"message": "No token provided"
}
}
< /code>
Что в моем app.py:
app = Flask(__name__)
app.jinja_env.globals.update(zip=zip)
app.secret_key = 'secret-key'
CLIENT_ID = 'client-id'
CLIENT_SECRET = 'client-secret'
REDIRECT_URI = 'http://localhost:5000/callback'
AUTH_URL = 'https://accounts.spotify.com/authorize'
TOKEN_URL = 'https://accounts.spotify.com/api/token'
API_BASE_URL = 'https://api.spotify.com/v1/'
sp = spotipy.Spotify(auth_manager=SpotifyClientCredentials(client_id=CLIENT_ID, client_secret=CLIENT_SECRET))
...
@app.route('/login')
def login():
scope = 'user-read-private user-read-email user-library-read user-top-read'
params = {
'client_id': CLIENT_ID,
'response_type': 'code',
'scope': scope,
'redirect_uri': REDIRECT_URI,
'show_dialog': True # set to False after testing
}
auth_url = f"{AUTH_URL}?{urllib.parse.urlencode(params)}"
return redirect(auth_url)
@app.route('/callback')
def callback():
if 'error' in request.args:
return jsonify({"error": request.args['error']})
# Login successful
if 'code' in request.args:
# Build request body with data to be sent to Spotify to get access token
req_body = {
'code': request.args['code'],
'grant_type': 'authorization_code',
'redirect_uri': REDIRECT_URI,
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET
}
response = requests.post(TOKEN_URL, data=req_body)
token_info = response.json()
session['access_token'] = token_info['access_token']
session['refresh_token'] = token_info['refresh_token']
session['expires_at'] = datetime.now().timestamp() + token_info['expires_in']
# Access token only lasts for 1 day
# Fetch user profile
user_profile = requests.get(API_BASE_URL + 'me', headers={'Authorization': f"Bearer {token_info['access_token']}"})
user_info = user_profile.json()
# Store additional user profile data in session
session['user_name'] = user_info['display_name']
session['user_id'] = user_info['id']
session['user_email'] = user_info['email']
session['user_uri'] = user_info['uri']
session['user_link'] = user_info['external_urls']['spotify']
session['user_image'] = user_info['images'][0]['url'] if user_info.get('images') else None
return redirect(url_for('home'))
@app.route('/refresh-token')
def refresh_token():
# Check if refresh token is NOT in the session, redirect to login
if 'refresh_token' not in session:
return redirect(url_for('login'))
# If access token is expired, make a request to get a fresh one
if datetime.now().timestamp() > session['expires_at']:
req_body = {
'grant_type': 'refresh_token',
'refresh_token': session['refresh_token'],
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET
}
response = requests.post(TOKEN_URL, data=req_body)
new_token_info = response.json()
# Override the access token we had before
session['access_token'] = new_token_info['access_token']
session['expires_at'] = datetime.now().timestamp() + new_token_info['expires_in']
return redirect(url_for('recommend'))
< /code>
Это маршрут, который связан с музыкальной рекомендацией: < /p>
@app.route('/new_user_recommendations', methods=['POST'])
def new_user_recommendations():
# Ensure the user is logged in
if 'access_token' not in session:
return jsonify({"error": "Please log in to use this feature"}), 401
# Retrieve artist names from the form
artist_names = [request.form.get(f'artist{i}') for i in range(1, 4)]
# Key mapping for human-readable keys
key_mapping = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
# Validate and fetch artist IDs
seed_artists = []
input_audio_features = []
for artist_name in artist_names:
if not artist_name:
return jsonify({"error": f"Missing artist name for input {artist_names.index(artist_name) + 1}"}), 400
search_result = sp.search(f'artist:"{artist_name}"', type='artist', limit=1)
if search_result['artists']['items']:
artist_id = search_result['artists']['items'][0]['id']
seed_artists.append(artist_id)
# Fetch top tracks and audio features for the artist
top_tracks = sp.artist_top_tracks(artist_id)['tracks']
track_ids = [track['id'] for track in top_tracks]
audio_features = sp.audio_features(track_ids)
# Average the features for visualization
normalized_features = {
'tempo': np.mean([feat['tempo'] for feat in audio_features if feat]),
'energy': np.mean([feat['energy'] for feat in audio_features if feat]),
'danceability': np.mean([feat['danceability'] for feat in audio_features if feat]),
'valence': np.mean([feat['valence'] for feat in audio_features if feat])
}
input_audio_features.append(normalized_features)
else:
return jsonify({"error": f"Artist '{artist_name}' not found"}), 404
# Validate that we have enough artists
if len(seed_artists) < 1:
return jsonify({"error": "No valid artists found for recommendations"}), 400
# Construct the API request
headers = {
'Authorization': f"Bearer {session['access_token']}"
}
params = {
'seed_artists': ','.join(seed_artists),
'limit': 20
}
# Add dynamic target features as needed, e.g., tempo, danceability
# params['target_tempo'] = 120
url = f'https://api.spotify.com/v1/recommendations?{urllib.parse.urlencode(params)}'
try:
response = requests.get(url, headers=headers)
response.raise_for_status()
recommendations = response.json()
# Process recommendations
recommended_tracks = []
for track in recommendations.get('tracks', []):
# Fetch the genres for each artist in the track
track_genres = []
for artist in track['artists']:
artist_id = artist['id']
artist_info = sp.artist(artist_id)
artist_genres = artist_info.get('genres', [])
track_genres.extend(artist_genres)
recommended_tracks.append({
'track_name': track['name'],
'artists': ', '.join(artist['name'] for artist in track['artists']),
'album_name': track['album']['name'],
'popularity': track['popularity'],
'preview_url': track['preview_url'],
'genres': track_genres, # Add genres to the track
'id': track.get('id')
})
# Fetch audio features for recommended tracks
recommendation_ids = [track['id'] for track in recommended_tracks if track['id']]
rec_audio_features = sp.audio_features(recommendation_ids)
recommended_audio_features = [
{
'tempo': round(feat['tempo']),
'key': key_mapping[feat['key']],
'energy': feat['energy'],
'danceability': feat['danceability'],
'valence': feat['valence']
}
for feat in rec_audio_features if feat
]
if not recommended_tracks:
return jsonify({"error": "No recommendations found. Try with different artists"}), 404
# Render the template
return render_template(
'new_user.html',
recommendations=recommended_tracks,
input_features=input_audio_features,
recommendation_features=recommended_audio_features
)
except requests.exceptions.RequestException as e:
return jsonify({"error": f"Error fetching recommendations: {str(e)}"}), 500
< /code>
Traceback упомянул, что ошибка здесь заключается в ", Line 358 , в new_user_recommendations
audio_features = sp.audio_features(track_ids)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
< /code>
оцените любую предоставленную помощь или руководство. ID и секрет, но это все еще не работает.
Я создаю систему рекомендаций Spotify, используя колбу и Spotipy. У меня есть функция, в которой система может генерировать 20 рекомендаций по песням на основе артистов, которые пользователь ввел в форму HTML. Все могло бежать неделю назад без ошибок. Однако, когда я продолжал работать над этой системой в последние несколько дней, я получал SpotifyException и не смог пройти ее. Я не внес никаких изменений в свой код с того дня, как он работал.[code]spotipy.exceptions.SpotifyException: http status: 403, code:-1 - https://api.spotify.com/v1/audio-features/?ids=1BxfuPKGuaTgP7aM0Bbdwr,2OzhQlSqBEmt7hmkYxfT6m,4q5YezDOIPcoLr8R81x9qy,3hUxzQpSfdDqwM3ZTFQY0K,4R2kfaDFhslZEMJqAFNpdd,1dGr1c8CrMLDpV6mPbImSI,1R0a2iXumgCiFb7HEZ7gUE,0V3wPSX9ygBnCm8psDIegu,1u8c2t2Cy7UBoG4ArRcF5g,0W0iAC1VGlB82PI6elxFYf: None, reason: None[/code] Я получил эту ошибку в консоли: [code]HTTP Error for GET to https://api.spotify.com/v1/audio-features/?ids=1BxfuPKGuaTgP7aM0Bbdwr,2OzhQlSqBEmt7hmkYxfT6m,4q5YezDOIPcoLr8R81x9qy,3hUxzQpSfdDqwM3ZTFQY0K,4R2kfaDFhslZEMJqAFNpdd,1dGr1c8CrMLDpV6mPbImSI,1R0a2iXumgCiFb7HEZ7gUE,0V3wPSX9ygBnCm8psDIegu,1u8c2t2Cy7UBoG4ArRcF5g,0W0iAC1VGlB82PI6elxFYf with Params: {} returned 403 due to None[/code] Я получил это, когда нажал ссылку на вызов API: [code]{ "error": { "status": 401, "message": "No token provided" } } < /code> Что в моем app.py: app = Flask(__name__) app.jinja_env.globals.update(zip=zip) app.secret_key = 'secret-key'
@app.route('/callback') def callback(): if 'error' in request.args: return jsonify({"error": request.args['error']})
# Login successful if 'code' in request.args: # Build request body with data to be sent to Spotify to get access token req_body = { 'code': request.args['code'], 'grant_type': 'authorization_code', 'redirect_uri': REDIRECT_URI, 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET }
# Store additional user profile data in session session['user_name'] = user_info['display_name'] session['user_id'] = user_info['id'] session['user_email'] = user_info['email'] session['user_uri'] = user_info['uri'] session['user_link'] = user_info['external_urls']['spotify'] session['user_image'] = user_info['images'][0]['url'] if user_info.get('images') else None
return redirect(url_for('home'))
@app.route('/refresh-token') def refresh_token(): # Check if refresh token is NOT in the session, redirect to login if 'refresh_token' not in session: return redirect(url_for('login'))
# If access token is expired, make a request to get a fresh one if datetime.now().timestamp() > session['expires_at']: req_body = { 'grant_type': 'refresh_token', 'refresh_token': session['refresh_token'], 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET }
# Override the access token we had before session['access_token'] = new_token_info['access_token'] session['expires_at'] = datetime.now().timestamp() + new_token_info['expires_in']
return redirect(url_for('recommend')) < /code> Это маршрут, который связан с музыкальной рекомендацией: < /p> @app.route('/new_user_recommendations', methods=['POST']) def new_user_recommendations(): # Ensure the user is logged in if 'access_token' not in session: return jsonify({"error": "Please log in to use this feature"}), 401
# Retrieve artist names from the form artist_names = [request.form.get(f'artist{i}') for i in range(1, 4)]
# Validate and fetch artist IDs seed_artists = [] input_audio_features = [] for artist_name in artist_names: if not artist_name: return jsonify({"error": f"Missing artist name for input {artist_names.index(artist_name) + 1}"}), 400
# Fetch top tracks and audio features for the artist top_tracks = sp.artist_top_tracks(artist_id)['tracks'] track_ids = [track['id'] for track in top_tracks] audio_features = sp.audio_features(track_ids)
# Average the features for visualization normalized_features = { 'tempo': np.mean([feat['tempo'] for feat in audio_features if feat]), 'energy': np.mean([feat['energy'] for feat in audio_features if feat]), 'danceability': np.mean([feat['danceability'] for feat in audio_features if feat]), 'valence': np.mean([feat['valence'] for feat in audio_features if feat]) } input_audio_features.append(normalized_features) else: return jsonify({"error": f"Artist '{artist_name}' not found"}), 404
# Validate that we have enough artists if len(seed_artists) < 1: return jsonify({"error": "No valid artists found for recommendations"}), 400
# Construct the API request headers = { 'Authorization': f"Bearer {session['access_token']}" } params = { 'seed_artists': ','.join(seed_artists), 'limit': 20 } # Add dynamic target features as needed, e.g., tempo, danceability # params['target_tempo'] = 120
# Process recommendations recommended_tracks = [] for track in recommendations.get('tracks', []): # Fetch the genres for each artist in the track track_genres = [] for artist in track['artists']: artist_id = artist['id'] artist_info = sp.artist(artist_id) artist_genres = artist_info.get('genres', []) track_genres.extend(artist_genres)
recommended_tracks.append({ 'track_name': track['name'], 'artists': ', '.join(artist['name'] for artist in track['artists']), 'album_name': track['album']['name'], 'popularity': track['popularity'], 'preview_url': track['preview_url'], 'genres': track_genres, # Add genres to the track 'id': track.get('id') })
# Fetch audio features for recommended tracks recommendation_ids = [track['id'] for track in recommended_tracks if track['id']] rec_audio_features = sp.audio_features(recommendation_ids) recommended_audio_features = [ { 'tempo': round(feat['tempo']), 'key': key_mapping[feat['key']], 'energy': feat['energy'], 'danceability': feat['danceability'], 'valence': feat['valence'] } for feat in rec_audio_features if feat ]
if not recommended_tracks: return jsonify({"error": "No recommendations found. Try with different artists"}), 404
except requests.exceptions.RequestException as e: return jsonify({"error": f"Error fetching recommendations: {str(e)}"}), 500 < /code> Traceback упомянул, что ошибка здесь заключается в ", Line 358 , в new_user_recommendations [/code] audio_features = sp.audio_features(track_ids) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ < /code> оцените любую предоставленную помощь или руководство. ID и секрет, но это все еще не работает.
Я создаю систему рекомендаций Spotify, используя колбу и Spotipy. У меня есть функция, в которой система может генерировать 20 рекомендаций по песням на основе артистов, которые пользователь ввел в форму HTML. Все могло бежать неделю назад без...
Я создаю систему рекомендаций Spotify, используя Flask и Spotipy. У меня есть функция, позволяющая системе генерировать 20 рекомендаций по песням на основе исполнителей, которых пользователь ввел в HTML-форму. Неделю назад все работало без ошибок....
Это код, который я использую для извлечения данных с веб -сайта Spotify с использованием библиотеки Spotipy и Python. Я могу получить данные с помощью аутентификации, но я также могу получить только свои пользовательские данные и через их поисковый...
Это код, который я использую для извлечения данных с веб -сайта Spotify с использованием библиотеки Spotipy и Python. Я могу получить данные с помощью аутентификации, но я также могу получить только свои пользовательские данные и через их поисковый...