· 2 min read
Watching a Spotify catalog for tracks that go dark
by Furkan Durna · Project: Track Analyzer
#python #fastapi #react
When you manage music releases, a track quietly becoming unplayable in some countries is easy to miss and costly to leave unfixed. Track Analyzer is an internal tool for two operators that scans playlists and artist catalogs for that, and tracks stream counts over time. It is a FastAPI backend with a React panel.
Finding unplayable tracks
The backend uses Spotify's official Web API with app-level credentials, so no user login is involved. There are three kinds of scan:
- Playlists. It pages through a playlist 100 tracks at a time, requesting only the fields it needs and optionally for one market, and flags any track Spotify reports as not playable. New findings are saved without overwriting earlier ones.
- Artist catalogs. It walks an artist's albums and tracks and checks each track's list of available markets against the region being checked.
- Discovery. Starting from an artist name, it searches playlists, then crawls the other playlists of each playlist's owner, down to a configurable depth. This finds places an artist appears that nobody listed by hand.
Tracks are fetched in batches of 50 and albums in batches of 20, which also fills in release identifiers missing from the smaller album objects.
Stream counts from somewhere else
Spotify's public API has no stream counts. Those come from Soundcharts, a commercial music data API. Each Spotify track ID is mapped to a Soundcharts ID once and cached, then its daily audience data is fetched.
Soundcharts returns roughly the last 90 days by default, but the tool keeps more than that. Each update only adds dates it doesn't already have, so the stored history keeps growing past the window. From that history the panel computes a daily average: the mean of the non-negative day-to-day differences, which ignores corrections in the source data. Tracks averaging more than 5,000 streams a day are promoted to a priority list.
Being a polite API client took some work:
- Rate limits: requests are retried when rate-limited, using the wait time the API returns.
- Quota: a "forbidden" answer is treated as an exhausted quota rather than a broken track.
- Bulk updates: they run in the background with a pause between tracks.
- Failures: failing tracks are remembered and skipped next time, except "not found" results, since a song may be added to the data source later.
The panel
The React panel has pages for tracks, the database, artist scans, playable and flagged artists, and lookups. Stream history is drawn with Recharts, and a region selector switches the market being checked. The interface is in Turkish, since that's who uses it.
Where it stands
It's a working internal tool with rough edges. Data lives in SQLite, which suits two users. A scheduler for automatic periodic scans exists but isn't connected yet, so scans are started from the panel. Popularity and playlist contents are stored as their latest values only, so trends in those aren't tracked yet. Source is on GitHub.