🚀 Executive Summary

TL;DR: Accidental playlist deletion highlights the fragility of digital assets. This guide provides a Python script using `spotipy` to back up Spotify playlists to a JSON file, offering peace of mind and structured data for future use.

🎯 Key Takeaways

  • Spotify API authentication requires creating an application in the Developer Dashboard, obtaining Client ID and Secret, and crucially setting `http://localhost:8888/callback` as a Redirect URI for `spotipy`’s OAuth flow.
  • The script leverages `spotipy` for Spotify API interaction and `python-dotenv` to securely manage API credentials and user information in a `config.env` file, preventing hardcoding of sensitive data.
  • Effective data collection from the Spotify API necessitates proper pagination handling using `sp.next()` for both playlists and their tracks, ensuring all items are captured and preventing incomplete backups.

Backup Spotify Playlists to a JSON File using Python

Backup Spotify Playlists to a JSON File using Python

Hey team, Darian here. A few months back, a friend of mine accidentally deleted a collaborative playlist we’d been building for years. It was a painful reminder that digital assets, even playlists, are fragile. That incident got me thinking about applying some DevOps principles to my personal life. I now run a simple Python script to back up my entire Spotify library to a version-controlled JSON file. It’s saved me more than once, and today I’m going to walk you through how to build it. This is a quick win that gives you real peace of mind.

Prerequisites

Before we jump in, make sure you have the following ready. I’m assuming you’re comfortable with the basics, so we can focus on the important parts.

  • Python 3 installed on your machine.
  • A Spotify account (Free or Premium will work).
  • Access to the Spotify Developer Dashboard to create an application.
  • A way to install Python packages. We’ll be using `spotipy` and `python-dotenv`.

The Guide: Step-by-Step

Step 1: Get Your Spotify API Credentials

First things first, we need to tell Spotify that our script is allowed to access our data.

  1. Navigate to your Spotify Developer Dashboard and log in.
  2. Click “Create App”. Give it a name and description (e.g., “Playlist Backup Script”).
  3. Once created, you’ll see your Client ID and a button to show your Client Secret. Keep these handy; we’ll need them in a minute.
  4. Now, this is a crucial step that trips people up: Click “Edit Settings”. Under “Redirect URIs”, add http://localhost:8888/callback. Even though our script isn’t a web app, the authentication flow `spotipy` uses requires this to capture the auth token.
  5. Save your changes. That’s it for the dashboard.

Step 2: Setting Up Your Local Environment

In my production setups, I containerize everything, but for a local script, a virtual environment is perfect. I’ll skip the standard `venv` setup commands since you likely have your own workflow for that. Let’s jump straight to the dependencies and configuration.

You’ll need two main packages. You can install them with pip: `spotipy` is the excellent Python library for the Spotify API, and `python-dotenv` is my go-to for managing environment variables securely.

Next, in your project directory, create a file named config.env. This is where we’ll store our secrets so they aren’t hardcoded in our script—a non-negotiable best practice.


# config.env
SPOTIPY_CLIENT_ID='YOUR_CLIENT_ID_HERE'
SPOTIPY_CLIENT_SECRET='YOUR_CLIENT_SECRET_HERE'
SPOTIPY_REDIRECT_URI='http://localhost:8888/callback'
# Add your Spotify username below
SPOTIFY_USERNAME='YOUR_SPOTIFY_USERNAME'

Replace the placeholder values with the credentials you got from the developer dashboard and your own Spotify username.

Step 3: The Python Backup Script

Alright, let’s write the code. Create a file named backup_playlists.py. The logic is straightforward: authenticate, get the list of playlists, loop through each one to get its tracks, and then dump all that data into a single JSON file.


import os
import json
import spotipy
from spotipy.oauth2 import SpotifyOAuth
from dotenv import load_dotenv
import datetime

def backup_spotify_playlists():
    # Load environment variables from config.env
    load_dotenv('config.env')

    # The 'scope' defines the permissions our script is asking for.
    # 'playlist-read-private' is what we need to see our private playlists.
    scope = "playlist-read-private"

    try:
        sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))
        user_id = sp.me()['id']
        print(f"Successfully authenticated as user: {user_id}")
    except Exception as e:
        print(f"Error during authentication: {e}")
        return # Exit the function if auth fails

    # This dictionary will hold all our playlist data
    all_playlists_data = {
        'export_date': datetime.datetime.now().isoformat(),
        'user_id': user_id,
        'playlists': []
    }

    # Fetch the user's playlists
    playlists = sp.current_user_playlists()

    # Loop through each playlist
    while playlists:
        for i, playlist in enumerate(playlists['items']):
            playlist_id = playlist['id']
            playlist_name = playlist['name']
            print(f"Processing playlist: {playlist_name}...")

            playlist_data = {
                'name': playlist_name,
                'id': playlist_id,
                'description': playlist['description'],
                'owner': playlist['owner']['display_name'],
                'tracks': []
            }

            # Fetch all tracks in the playlist (handles pagination automatically)
            tracks_response = sp.playlist_items(playlist_id)
            while tracks_response:
                for item in tracks_response['items']:
                    track = item['track']
                    # Some tracks might not have metadata (e.g., local files), so we check
                    if track:
                        playlist_data['tracks'].append({
                            'name': track['name'],
                            'artist': ", ".join([artist['name'] for artist in track['artists']]),
                            'album': track['album']['name'],
                            'id': track['id']
                        })
                
                # Check if there is a next page of tracks
                if tracks_response['next']:
                    tracks_response = sp.next(tracks_response)
                else:
                    tracks_response = None
            
            all_playlists_data['playlists'].append(playlist_data)

        # Check for the next page of playlists
        if playlists['next']:
            playlists = sp.next(playlists)
        else:
            playlists = None

    # Write the collected data to a JSON file
    file_name = f"spotify_backup_{datetime.date.today()}.json"
    with open(file_name, 'w', encoding='utf-8') as f:
        json.dump(all_playlists_data, f, ensure_ascii=False, indent=4)
    
    print(f"\nBackup complete! Data saved to {file_name}")

if __name__ == '__main__':
    backup_spotify_playlists()

Pro Tip: Notice how we handle pagination for both the playlists list and the tracks within each playlist. The Spotify API returns results in “pages” (usually 50-100 items at a time). The `spotipy` library makes this easy with the `sp.next()` method. Forgetting to handle pagination is the #1 reason scripts like this fail to capture all data.

The first time you run this script, your web browser will open, asking you to authorize the application. Once you agree, you’ll be redirected to that `localhost` URL, and the script will capture the token it needs to proceed. It will cache this token for future runs, so you’ll only have to do this once.

Common Pitfalls (Where I Usually Mess Up)

  • Redirect URI Mismatch: If the URI in your `config.env` file doesn’t exactly match one of the URIs you entered in the Spotify Developer Dashboard, the authentication will fail. No trailing slashes, no typos.
  • Incorrect Scopes: If you get a “Permission denied” or `403` error, it’s almost always a scope issue. You must request the right permissions. We used `playlist-read-private` here, but if you wanted to modify playlists, you’d need something like `playlist-modify-public`.
  • Handling Null Tracks: Sometimes a playlist can contain items that aren’t available tracks (like a podcast episode or a deleted song). The `if track:` check in the code prevents the script from crashing when it encounters one of these.

Conclusion

And there you have it. You now have a reliable, automated way to back up your Spotify playlists to a clean, readable JSON file. This file is not just a backup; it’s structured data you can use for other projects, like migrating to another service or running your own analytics.

For a true DevOps approach, the next step is automation. I have this running on a small home server. A simple cron job handles it for me every week, so I never have to think about it. You could set one up like this:

0 2 * * 1 python3 backup_playlists.py

This runs the script at 2 AM every Monday. It’s a classic “set it and forget it” solution. Hope this helps you protect your hard-earned music collections!

Darian Vance - Lead Cloud Architect

Darian Vance

Lead Cloud Architect & DevOps Strategist

With over 12 years in system architecture and automation, Darian specializes in simplifying complex cloud infrastructures. An advocate for open-source solutions, he founded TechResolve to provide engineers with actionable, battle-tested troubleshooting guides and robust software alternatives.


🤖 Frequently Asked Questions

âť“ How do I securely store my Spotify API credentials for the backup script?

Spotify API credentials (Client ID, Client Secret, Redirect URI, and Spotify username) should be stored in a `config.env` file and loaded using `python-dotenv` to prevent hardcoding them directly in the Python script.

âť“ How does this Python script approach compare to manual playlist export or third-party backup services?

This Python script offers an automated, version-controllable, and highly customizable solution for backing up Spotify playlists to a structured JSON file, unlike manual exports which are often limited or third-party services that may pose privacy concerns or lack flexibility.

âť“ What is a common reason for authentication failure when setting up the Spotify playlist backup script?

A common pitfall is a ‘Redirect URI Mismatch,’ where the URI in `config.env` does not exactly match one configured in the Spotify Developer Dashboard. Ensure `http://localhost:8888/callback` is precisely entered in both locations.

Leave a Reply

Discover more from TechResolve - SaaS Troubleshooting & Software Alternatives

Subscribe now to keep reading and get access to the full archive.

Continue reading