Skip to content

Instantly share code, notes, and snippets.

@TheMuellenator
Forked from angelabauer/main.py
Last active August 12, 2025 20:31
Show Gist options
  • Save TheMuellenator/c84616c21f0f9ce68c12c357d3e1c794 to your computer and use it in GitHub Desktop.
Save TheMuellenator/c84616c21f0f9ce68c12c357d3e1c794 to your computer and use it in GitHub Desktop.
sp = spotipy.Spotify(
auth_manager=SpotifyOAuth(
scope="playlist-modify-private",
redirect_uri="http://example.com",
client_id=YOUR UNIQUE CLIENT ID,
client_secret= YOUR UNIQUE CLIENT SECRET,
show_dialog=True,
cache_path="token.txt"
)
)
user_id = sp.current_user()["id"]
date = input("Which year do you want to travel to? Type the date in this format YYYY-MM-DD: ")
song_uris = ["The list of", "song URIs", "you got by", "searching Spotify"]
playlist = sp.user_playlist_create(user=user_id, name=f"{date} Billboard 100", public=False)
# print(playlist)
sp.playlist_add_items(playlist_id=playlist["id"], items=song_uris)
@a-k-14
Copy link

a-k-14 commented Jun 29, 2025

I have added few more features:

  • get the list of playlists in a user profile
  • check if there is an empty playlist and if yes, get its 'id'
  • if no playlists exist or if no empty playlists exist, create a new playlist and get its id
  • time taken to execute the program completely

This way we can have new playlist on every run.

Note: Spotify takes some time to report the proper track count in a playlist. So, if you create a new empty playlist, add some songs to it, and immediately run the code again, the previously created playlist will be reported as empty. I think it takes roughly 15sec to get the updated count.

`

GOAL - to create a spotify playlist of top 100 songs on billboard.com on a selected day

import requests
from bs4 import BeautifulSoup
import time
import spotipy
from spotipy.oauth2 import SpotifyOAuth
import pprint

spotify_client_id = "..."
spotify_client_secret = "..."
spotify_redirect_uri = "https://example.com/"

def get_top_100_titles(selected_date) -> list:
"""
Fetches the top 100 titles for a selected date from billboard.com and returns
:return: list of top 100 titles
"""
print(f"Getting top 100 titles on {selected_date} from billboard...")

header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:131.0) Gecko/20100101 Firefox/131.0"}
billboard_url = "https://www.billboard.com/charts/hot-100/" + selected_date.strip()

response = requests.get(url=billboard_url, headers=header)
response.raise_for_status()
website = response.text

soup = BeautifulSoup(website, "html.parser")

# list_items = soup.find_all(name="li", class_="o-chart-results-list__item")
list_items = soup.select("li ul li h3")

titles = [item.string.strip() for item in list_items]

# for item in list_items:
# title_h3 = item.find(name="h3", attrs={"class":"c-title"})
# if title_h3:
#     titles.append(title_h3.string.strip())
return titles

def write_data(selected_date, data: list) -> None:
"""
Writes the data to a text file
:param selected_date: user selected date
:param data: list
:return: None
"""
print("Adding the top 100 songs to the file...")

with open("top_100.txt", "w") as file:
    file.write(f"{selected_date}\n")
    for i in range(len(data)):
        file.write(f"{i + 1}. {data[i]}\n")

def humanize_time(seconds) -> None:
intervals = [("d", 86400), ("h", 3600), ("m", 60)]
parts = []
if seconds:
for label, count in intervals:
value, seconds = divmod(seconds, count)

        if value:
            parts.append(f"{value:.0f}{label}")

parts.append(f"{seconds:.02f}s")
print(" ".join(parts))

def add_to_playlist(date, titles_to_add):
print("Authenticating with Spotify...")
# steps to add the title to the user's spotify playlist
# 1. get client_id, client_secret from spotify

# 2. get authorization token from spotify using spotipy
# spotify authorization
# playlist-modify-private
# scope = "user-library-read"
scope = "playlist-modify-public"
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope, client_id=spotify_client_id,
                                               client_secret=spotify_client_secret, redirect_uri=spotify_redirect_uri, show_dialog=True, cache_path="token.txt", username="vgst cof"))
user_id = sp.current_user()["id"]

# 3. get an empty playlist id from spotify

# get the list of playlists in a user profile
print("Fetching list of playlists...")
playlist_search_results = sp.current_user_playlists()["items"]

# check if there are any empty playlists and get its id
empty_playlist_id = None
if playlist_search_results:
    print(f"{len(playlist_search_results)} playlists exist")
    # there are playlists in the user profile
    for playlist in playlist_search_results:
        no_of_tracks = int(playlist["tracks"]["total"])
        if not no_of_tracks:
            print(no_of_tracks)
            empty_playlist_id =  playlist["id"]
            empty_playlist_name = playlist["name"]
            print(f"Empty playlist name: {empty_playlist_name}")
            break

if not playlist_search_results or not empty_playlist_id:
    print("No playlists or no empty playlists exist, creating a new playlist...")
    # if there are no playlists or if there are no empty playlists, create a new playlist
    new_empty_playlist = sp.user_playlist_create(user=user_id, name=f"Top 100 {date}")
    empty_playlist_id = new_empty_playlist["id"]
    empty_playlist_name = new_empty_playlist["name"]
    print(f"New empty playlist name: {empty_playlist_name}")


# 4. get the id of the title
print("Adding tracks to the the playlist", end="")
titles_with_ids = []
for title in titles_to_add:
    print(".", end="")
    search_results = sp.search(q="track:" + title, type="track")["tracks"]["items"]
    if search_results:
        # if the title exists in spotify db
        title_id = search_results[0]["id"]
        titles_with_ids.append(title_id)
    else:
        print(title, "does not exist in Spotify. Skipped.")

# 5. add the title to the user's playlist
sp.playlist_add_items(playlist_id=empty_playlist_id, items=titles_with_ids)

#--------------------#--------------------#

get the date from the user

user_chosen_date = input("Which year do you want to travel to? Type the date in YYYY-MM-DD: ")

to track the time for program execution

start_t = time.time()

get the top 100 songs/titles for the selected date

top_100_titles = get_top_100_titles(user_chosen_date)

if top_100_titles:
# write the titles to a text file
write_data(user_chosen_date, top_100_titles)
# add tracks to the user's playlist
add_to_playlist(user_chosen_date, top_100_titles)

end_t = time.time()

humanize_time(end_t - start_t)

`

@entfy
Copy link

entfy commented Aug 12, 2025

import requests, spotipy, os
from dotenv import load_dotenv
from spotipy.oauth2 import SpotifyOAuth


load_dotenv()

class SpotifyManager:

    def __init__(self):
        self._user=os.environ["SPOTIFY_CLIENT_ID"]
        self._password=os.environ["SPOTIFY_CLIENT_SECRET"]
        self._sp = self._create_object()
        self._user_id = self._get_user_id()
        self.song_names = []
        self.song_artists = []
        self.track_uris = []
        self.results = []
        
        
    def _create_object(self):
        return spotipy.Spotify(
            auth_manager=SpotifyOAuth(
                scope="playlist-modify-private",
                redirect_uri="https://example.com",
                client_id=self._user,
                client_secret=self._password,
                cache_path="token.txt",
                username=""
            )
        )
        
    
    def _get_user_id(self):
        
        return self._sp.current_user()['id']
    
    
    def create_top100_playlist(self, date):
        
        self.get_track_uris(self.song_names)
        self.add_tracks_playlist(self.create_playlist(date))
        
    
    def create_playlist(self, date):
        
        new_playlist = self._sp.user_playlist_create(
            user=self._user_id,
            name=f"Top 100 on {date}",
            public=False,
            description=f"Billboard Top 100 Playlist from {date}"
        )
        
        return new_playlist['id']
        
    def get_track_uris(self, songs):
        
        for song in songs:
            result = self._sp.search(q=song, type='track', limit=10)
            self.results.append(result)
            
            try:
                uri = result['tracks']['items'][0]['uri']
                self.track_uris.append(uri)
            except IndexError:
                print(f"{song} doesn't exist in Spotify. Skipped")
                
                
    def add_tracks_playlist(self, playlist_id):
        
        self._sp.user_playlist_add_tracks(user=self._user_id, playlist_id=playlist_id, tracks=self.track_uris)
import requests, spotipy, os
from bs4 import BeautifulSoup
from dotenv import load_dotenv
from data_manager import SpotifyManager

load_dotenv()

spotifymanager = SpotifyManager()

date = input("Which year do you want to travel to? Type the year in this format YYYY-MM-DD: ")

URL="https://www.billboard.com/charts/hot-100/"
header = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Safari/605.1.15"
}

response = requests.get(url=f"{URL}{date}", headers=header)
soup = BeautifulSoup(response.text, "html.parser")

song_names_spans = soup.select("li ul li h3")
spotifymanager.song_names = [song.getText().strip() for song in song_names_spans]

song_artist_spans = soup.select("li ul li h3+span")
spotifymanager.song_artists = [artist.getText().strip() for artist in song_artist_spans]

spotifymanager.create_top100_playlist(date)

It took a bit because the documentation isn't the greatest for Spotipy, but after doing everything based on Spotify API, I used the Spotipy package and got it solved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment