No audio dependency
The classifier operates on metadata and tags, so it can run without storing copyrighted audio files.
AI-GENERATED PROJECT / 2026
A Python classification and publishing tool for a 2,604-track Spotify playlist.
This write-up—was generated with AI.
01 / CONSTRAINTS
Spotify supplied playlist reads and writes, but this development-mode app did not have dependable per-track genre or audio-feature data. Spotify therefore became the source and destination layer, while Last.fm supplied community tags for tracks, albums, and artists. The tool does not download or inspect audio.
The classifier operates on metadata and tags, so it can run without storing copyrighted audio files.
Coverage differs by song, counts are user-generated, and some tags describe fandoms rather than music.
The source playlist ID is rejected as a publish destination. Every write goes to a generated playlist.
Spotify pagination, 100-item write batches, Last.fm rate limits, and retries are handled explicitly.
02 / ARCHITECTURE
OAuth PKCE, paginated reads, normalized track records, and a saved source snapshot.
Track, album, primary-artist, and secondary-artist tags are cached separately.
Weighted evidence is scored against 19 programmed stations and a review bucket.
HTML and CSV inspection precede dry-run, batched writes, saved IDs, and remote verification.
data/source.json stores the normalized Spotify export.data/lastfm-cache.json prevents repeated enrichment calls.output/assignments.json stores tags, every station score, the winner, and confidence.data/published.json maps station IDs to destination playlist IDs for repeatable updates.03 / CLASSIFIER
The initial version treated artist genres as the main signal. That failed on artists whose catalog spans several styles. Version 4 uses an evidence hierarchy and changes the multipliers based on what is available for each individual song.
The track dominates. Album and artist tags only add context.
The album becomes the main signal when the track has no useful tags.
Artist evidence remains usable but carries less authority. Featured artists receive another 0.45 multiplier.
Duplicate evidence keeps its strongest weight and adds 18% of the weaker supporting vote.
Each station defines primary tags, secondary includes, exclusions, optional year ranges, and whether
a primary tag is mandatory. Generic labels such as pop, rock,
hip hop, and electronic receive lower multipliers, especially when they
come from artist-level evidence. Exclusion weight reduces a score multiplicatively, and final scores
use log1p to limit the effect of many overlapping tags.
A song is assigned only when the winning score reaches 0.19. Confidence is recorded as
(winner - runner_up) / winner. The current configuration keeps one destination per track,
but stores every score so overlap can be reviewed later.
04 / EVIDENCE COVERAGE
The review report exposes the selected station, confidence margin, evidence source, normalized tags, and all candidate scores. A CSV override file can replace any assignment without changing classifier code.
05 / OUTPUT DISTRIBUTION
Mainstream pop, dance-pop, and radio-sized hooks.
Pop-rock, adult contemporary, acoustic pop, and songwriters.
Indie, art, bedroom, and alternative pop.
K-pop, J-pop, C-pop, and East Asian hip-hop.
Synthpop, new wave, electroclash, and retro-futurism.
Hip-hop, boom bap, conscious, underground, and classic rap.
Trap, drill, cloud rap, emo rap, and southern rap.
Contemporary R&B, alternative R&B, neo-soul, and slow jams.
Alternative, indie, garage, grunge, and post-grunge rock.
Punk, pop-punk, emo, skate punk, and post-hardcore.
Metal, metalcore, nu metal, industrial, and hardcore.
House, techno, trance, progressive house, and club music.
Dubstep, drum and bass, future bass, and breakbeat.
Ambient, downtempo, trip-hop, chillout, and shoegaze.
Soul, funk, disco, Motown, boogie, and warm grooves.
Country, folk, Americana, roots, and storytelling.
Reggae, Latin, Afrobeats, dancehall, ska, and global music.
Classic, blues, southern, psychedelic, and arena rock.
Soundtracks, orchestral scores, classical, and instrumentals.
Missing, ambiguous, or below-threshold evidence.
06 / TRADEOFFS
It is reproducible, cheap to rerun, and easy to inspect. It cannot detect tempo, timbre, or mood directly.
Required primary tags and the 0.19 floor reduce false positives but leave 233 tracks for review.
The cache contains 2,566 track, 1,986 album, and 1,609 artist records. Refreshing is explicit.
This avoids duplicate playlists at the cost of hiding some genuine cross-genre relationships.
The last taxonomy change split a broad pop station into Headliners and The Avenue. Removing
pop rock and adult contemporary from Headliners produced a separate
127-track station without introducing overlaps.
07 / PUBLISHING
analyze and preview are read-only; only publish writes.publish --dry-run lists every intended create or update.