Create Playlists

This notebook uses Spotipy to create playlists for the song data collected previously programmatically.

import pandas as pd
import numpy as np
import math

import spotipy
from spotipy.oauth2 import SpotifyOAuth

from tqdm import tqdm
auth_manager = SpotifyOAuth(scope="playlist-modify-public", 
                            open_browser=False,  
                            cache_path="/datasets/commonfiles/spotify/cache")

Set OAuth Token

This only needs to be done once theoretically, and Spotipy will refresh as needed.

#auth_manager.get_authorize_url()
#auth_manager.get_access_token(token here, as_dict=False)

Authorize and get current user

spotify = spotipy.Spotify(auth_manager=auth_manager)
user_dict = spotify.current_user()
user_dict
{'display_name': 'Datafantic',
 'external_urls': {'spotify': 'https://open.spotify.com/user/31s4ct55ob6xjoghw4uxspvyu34u'},
 'followers': {'href': None, 'total': 0},
 'href': 'https://api.spotify.com/v1/users/31s4ct55ob6xjoghw4uxspvyu34u',
 'id': '31s4ct55ob6xjoghw4uxspvyu34u',
 'images': [],
 'type': 'user',
 'uri': 'spotify:user:31s4ct55ob6xjoghw4uxspvyu34u'}

App Code

df = pd.read_csv("songs.csv")
years = df['year'].unique()
years
array([1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968,
       1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979,
       1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990,
       1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
       2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
       2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022])
StartYear = '1958'
EndYear = '1958'
StartYear = 1990
EndYear = 2010

Some form validation to make sure the years make sense for the playlist.

if StartYear > EndYear:
    StartYear = EndYear

Let’s create our function that creates our Spotify playlist.

playlists = pd.read_csv("playlists.csv")
def check_playlists(playlist_name, playlists_df):
    """Checks if playlist has already been created. If so it aborts future creation."""
    result = playlists_df[playlists_df['name'] == playlist_name].shape[0]
    if result > 0:
        return False
    else:
        return True
def save_playlists(playlist, playlist_name, playlists_df):
    """Saves playlist in a csv file."""
    new_playlist = {
        'name':playlist_name,
        'id':playlist['id'],
        'link':playlist['external_urls']['spotify']
    }

    playlists_df = pd.concat([playlists_df, pd.DataFrame([new_playlist])])
    playlists_df.to_csv("playlists.csv", index=False)
def make_playlist(start_year, end_year):
    """Makes the playlist and adds tracks from songs.csv given the start and end year"""
    playlists_df = pd.read_csv("playlists.csv")
    if (start_year - end_year) == 0:
        playlist_name = f"Top US Singles: {start_year}"
    else:
        playlist_name = f"Top US Singles: {start_year}-{end_year}"

    if check_playlists(playlist_name, playlists_df):
        description = 'This playlist was generated automatically for a project on Datafantic.com.'
        playlist = spotify.user_playlist_create(user=user_dict['id'], 
                                                name=playlist_name,
                                                description=description)
        uris = list(df[(df['year'] >= start_year) & (df['year'] <= end_year)]['spotify_uri'].values)

        chunked_uris = np.array_split(uris, math.ceil(len(uris) / 100))
        for uri_list in chunked_uris:
            spotify.user_playlist_add_tracks(user=user_dict['id'], 
                                            playlist_id=playlist['id'], 
                                            tracks=uri_list)

        save_playlists(playlist, playlist_name, playlists_df)

Create Playlists

Since Deepnote published notebooks run in a stock environment, and I’m using Spotipy, I won’t be able to allow users to generate their own playlists on the fly. However I CAN create them programmatically. Since we have our functions above we can generate playlists from 1-20 years in width.

min(years)
1958
max(years)
2022

This code generate a list of tuples that contain our start and end years for each playlist.

year_pairs = []
for width in range(0,21):
    for year in years[:-width]:
        year_pairs.append((year, year+width))
len(year_pairs)
1090

We also need to make playlists for single years. This is very easy luckily as we can just loop through the years.

for year in years:
    make_playlist(year, year)

Now we can loop through our year pairs and make the long list of playlists.

year_pairs[0][0]
1958
for pair in tqdm(year_pairs):
    make_playlist(pair[0], pair[1])
100%|██████████| 1090/1090 [43:03<00:00,  2.37s/it]
df = pd.read_csv("playlists.csv")
df.shape
(1155, 3)

Created in deepnote.com Created in Deepnote