Skip to content

Commit cd65ff2

Browse files
committed
fix: add handling for empty response for audio features API endpoint
audio features endpoint is now deprecated and used by AI compalies to crawl data from spotify => always returns fixed 401.This commit adds a fallback to empty data if this situation is encountered while allowing the feature to be used when Spotify allows data fetching again.
1 parent 3acb4b4 commit cd65ff2

File tree

2 files changed

+33
-25
lines changed

2 files changed

+33
-25
lines changed

php/src/app/Crawler/SpotifyCrawler.php

+23-15
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ public function crawlAll(string $username): void
8181
$session = $spotifySession->getUnderlyingObject();
8282
$spotifyWebApi = $this->factory->getSpotifyWebAPI($session);
8383

84-
logs('crawler')->debug("starting spotify crawler for username $username");
84+
logs('crawler')->info("starting spotify crawler for username $username");
8585
$this->crawlTrackHistoryAndAudioFeatures($username, $spotifyWebApi);
86-
logs('crawler')->debug("finished spotify crawler for username $username");
86+
logs('crawler')->info("finished spotify crawler for username $username");
8787

8888
$this->sessionHandler->saveSession($spotifySession, $username);
8989
}
@@ -94,10 +94,10 @@ public function crawlAll(string $username): void
9494
protected function crawlTrackHistoryAndAudioFeatures(string $username, SpotifyWebAPI $spotifyWebApi): void
9595
{
9696
// TODO add "after" instead of limit if last crawl was last hour
97-
$recentTracks = $spotifyWebApi->getMyRecentTracks([
97+
$recentTracks = $spotifyWebApi->getMyRecentTracks([
9898
'limit' => config('services.spotify.crawl_bulk_limit'),
9999
])->items;
100-
logs('crawler')->debug("retrieved recent logs for user $username");
100+
logs('crawler')->info("retrieved recent logs for user $username");
101101

102102
$recentTracksIds = [];
103103
foreach ($recentTracks as $recentTrack) {
@@ -112,12 +112,13 @@ protected function crawlTrackHistoryAndAudioFeatures(string $username, SpotifyWe
112112
$artistIds[$artist->id] = $artist->id;
113113
}
114114
}
115-
115+
logs('crawler')->debug("getting artists for user $username");
116116
$artistsById = $this->getArtistsById($spotifyWebApi, $artistIds);
117+
logs('crawler')->debug("getting audio features for user $username");
117118
$audioFeatures = $this->getAudioFeatures($spotifyWebApi, $recentTracksIds);
118-
119+
logs('crawler')->debug("writing history for user $username");
119120
foreach ($recentTracks as $recentTrack) {
120-
$this->writeTrackHistoryPoint($audioFeatures[$recentTrack->track->id], $recentTrack, $username);
121+
$this->writeTrackHistoryPoint($audioFeatures[$recentTrack->track->id] ?? null, $recentTrack, $username);
121122
$this->writeGenreHistoryPoints($recentTrack, $artistsById, $username);
122123
}
123124

@@ -132,13 +133,17 @@ protected function crawlTrackHistoryAndAudioFeatures(string $username, SpotifyWe
132133
*/
133134
protected function getArtistsById(SpotifyWebAPI $spotifyWebApi, array $artistIds): array
134135
{
136+
logs('crawler')->debug("getting artists for user $username");
135137
$artistsFromAPI = $this->getCachedArtistsAndCleanupIds($artistIds);
138+
136139
$cache = Cache::tags([
137140
ServiceEnum::Spotify->value,
138141
ServiceEnum::Spotify->value . CacheKeyEnum::CACHE_KEY_SEPARATOR . CacheKeyEnum::Artist->value
139142
]);
140143

141-
if (count($artistIds) > 0) {
144+
$newArtistIdCount = count($artistIds);
145+
if (newArtistIdCount > 0) {
146+
logs('crawler')->debug("retrieving uncached data for $newArtistIdCount artists");
142147
// artistIds count could be more than crawl_bulk_limit
143148
$artistIdsChunks = array_chunk($artistIds, config('services.spotify.crawl_bulk_limit'));
144149

@@ -211,13 +216,16 @@ protected function getAudioFeatures(SpotifyWebAPI $spotifyWebApi, array $trackId
211216
logs('crawler')->debug("found audio feature for $trackId in cache");
212217
}
213218
}
214-
215219
if (count($trackIds) > 0) {
216-
$response = $spotifyWebApi->getMultipleAudioFeatures(array_values($trackIds));
217-
foreach ($response->audio_features as $audioFeature) {
218-
$cache->put($audioFeature->id, $audioFeature, config('services.spotify.cache_ttl'));
219-
$audioFeatures[$audioFeature->id] = $audioFeature;
220-
logs('crawler')->debug("set audio feature for $audioFeature->id to cache");
220+
try {
221+
$response = $spotifyWebApi->getMultipleAudioFeatures(array_values($trackIds));
222+
foreach ($response->audio_features as $audioFeature) {
223+
$cache->put($audioFeature->id, $audioFeature, config('services.spotify.cache_ttl'));
224+
$audioFeatures[$audioFeature->id] = $audioFeature;
225+
logs('crawler')->debug("set audio feature for $audioFeature->id to cache");
226+
}
227+
} catch (Exception $e) {
228+
logs('crawler')->warning('error while fetching audio feature, skipping. Exception: ' . $e->getMessage());
221229
}
222230
}
223231

@@ -227,7 +235,7 @@ protected function getAudioFeatures(SpotifyWebAPI $spotifyWebApi, array $trackId
227235
/**
228236
* @throws Exception
229237
*/
230-
protected function writeTrackHistoryPoint(stdClass $audioFeature, stdClass $track, string $username): void
238+
protected function writeTrackHistoryPoint(?stdClass $audioFeature, stdClass $track, string $username): void
231239
{
232240
$point = $this->factory->getTrackHistoryPoint(
233241
$username, ServiceEnum::Spotify->value, $audioFeature, $track

php/src/app/Factory.php

+10-10
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public function getSpotifyWebAPI(Session $session): SpotifyWebAPI
6060
public function getTrackHistoryPoint(
6161
string $username,
6262
string $service,
63-
stdClass $audioFeature,
63+
?stdClass $audioFeature,
6464
stdClass $track
6565
): Point {
6666
$artists = [];
@@ -81,15 +81,15 @@ public function getTrackHistoryPoint(
8181
->addField('track', $track->track->name)
8282
->addField('track_id', $track->track->id)
8383
->addField('duration_ms', (int)$track->track->duration_ms)
84-
->addField('danceability', (float)$audioFeature->danceability)
85-
->addField('energy', (float)$audioFeature->energy)
86-
->addField('key', (int)$audioFeature->key)
87-
->addField('speechiness', (float)$audioFeature->speechiness)
88-
->addField('acousticness', (float)$audioFeature->acousticness)
89-
->addField('instrumentalness', (float)$audioFeature->instrumentalness)
90-
->addField('liveness', (float)$audioFeature->liveness)
91-
->addField('valence', (float)$audioFeature->valence)
92-
->addField('tempo', round((float)$audioFeature->tempo))
84+
#->addField('danceability', (float)$audioFeature->danceability)
85+
#->addField('energy', (float)$audioFeature->energy)
86+
#->addField('key', (int)$audioFeature->key)
87+
#->addField('speechiness', (float)$audioFeature->speechiness)
88+
#->addField('acousticness', (float)$audioFeature->acousticness)
89+
#->addField('instrumentalness', (float)$audioFeature->instrumentalness)
90+
#->addField('liveness', (float)$audioFeature->liveness)
91+
#->addField('valence', (float)$audioFeature->valence)
92+
#->addField('tempo', round((float)$audioFeature->tempo))
9393
->time($playedAtDateTime);
9494
}
9595

0 commit comments

Comments
 (0)