Scrapes new tracks from curated Tidal playlists and exports them directly into a new Spotify playlist.
python3 track_playlists.pyThat's it. The script handles everything automatically from start to finish.
- Tidal is scraped — every playlist in
playlists.jsonis visited and checked for tracks added Today, Yesterday, or This Week- All artists on a track are captured (not just the first), so featuring/co-artist info is preserved
- A CSV is saved — a timestamped file is created in the
scraped-filesfolder, e.g.:scraped-files/SCRAPED 02-20-26__10.15.00 PM.csv - A Spotify playlist is created — a new private playlist is added to your Spotify account named:
🪁 DX 02-20-26 - All found tracks are added to that playlist automatically using a 3-step search strategy:
- Strategy 1: Title + Artist + Album (most precise)
- Strategy 2: Title + Artist only
- Strategy 3: Title only (broadest fallback — catches cases where Tidal/Spotify artist names differ)
- Detailed logging — each matched track shows what Spotify actually returned, e.g.:
This makes it easy to spot cases where the Spotify match is a different version of the song
[FOUND/EXPLICIT] Expectations - Adamn Killa → Expectations - Adamn Killa - The playlist opens in the Spotify desktop app automatically once it's been created
- A Keyboard Maestro macro is triggered (optional) — if
KM_MACRO_UUIDis set in.env, the macro is fired viaosascriptat the very end
If a track exists on multiple Tidal playlists, duplicates are removed before export.
The project organizes its output into two main directories:
scraped-files/— Stores timestamped CSVs of every matching track found on Tidal (Today/Yesterday/This Week). These serve as a historical record of what was "scraped" before the Spotify matching process begins.missed-tracks/— If a track found on Tidal cannot be confidently matched on Spotify (e.g., due to different artist formatting or if the track is not yet on Spotify), it is saved here in aMISSEDCSV. This makes it easy to manually find and add any tracks the script couldn't automate.
| Playlist | URL |
|---|---|
| Rap Bars & Melodies | Open |
| Thoro Hip-Hop | Open |
| Women of Hip-Hop | Open |
| Hip-Hop & R&B Club Music | Open |
| New Midwest | Open |
| Hip-Hop: RISING | Open |
| Viral Hype | Open |
| New West Coast | Open |
| New South | Open |
| Drill Hype | Open |
| New East Coast | Open |
To add or remove playlists, edit playlists.json.
pip install playwright spotipy python-dotenv
playwright install chromiumCreate a .env file in the project root:
SPOTIFY_CLIENT_ID=your_client_id
SPOTIFY_CLIENT_SECRET=your_client_secret
KM_MACRO_UUID=your_macro_uuid # optional — omit to skip the KM trigger
Get these from the Spotify Developer Dashboard.
Make sure http://127.0.0.1:8888/callback is added as a Redirect URI in your app settings.
You can trigger the full pipeline from anywhere on your Mac — via Script Editor, Raycast, Alfred, Keyboard Maestro,or any AppleScript-compatible launcher.
Save the following as a .scpt file in Script Editor:
set projectPath to "your path here"
-- Run the Python script and capture output
set scriptOutput to do shell script "cd " & quoted form of projectPath & " && python3 track_playlists.py"
-- Find the Spotify URI from the output
set spotifyURI to ""
repeat with outputLine in paragraphs of scriptOutput
if outputLine starts with "SPOTIFY_URI:" then
set spotifyURI to text 13 thru -1 of outputLine
exit repeat
end if
end repeat
-- Open the playlist in the Spotify desktop app
if spotifyURI is not "" then
tell application "Spotify"
activate
open location spotifyURI
end tell
else
display dialog "Playlist was created but could not find the Spotify URI in the script output." buttons {"OK"} default button "OK"
end ifHow it works:
- Runs
track_playlists.py, which scrapes Tidal and callsexport_to_spotify.py export_to_spotify.pyprints aSPOTIFY_URI:tag after the playlist is created- AppleScript captures that URI and opens the playlist directly in the Spotify desktop app