Announcements

Help Wizard

Step 1

NEXT STEP

Question regarding my Playlist project

Question regarding my Playlist project

Hi,

First of all, I would like to apologize if my question has already been answered, and extend a thank you to the devs for making this such a cool platform to build within.

I am beginning my work on a Playlist building application, it is simple, and rudimentary, but a passion project for my son, and I would love to ask some questions to some of the more advanced members here. I am using the free version of the API.

My goal is to create a playlist for my son, based off the individual tracks in his favorite playlists. He tends to become attached to individual artists and I thought this would be a great way to give him a playlist that features the artists top songs ๐Ÿ™‚

In essence, this is how my script operates:

  • The script fetches the first track from a playlist using sp.playlist_tracks().
  • For the selected track, it retrieves the lyrics from the Genius API using get_lyrics(). (to add to the description of the playlist)
  • it creates a new playlist using sp.user_playlist_create().
  • It fetches the cover art for the track using requests.get().
  • It uploads the cover image to the newly created playlist using upload_cover_image().
  • It retrieves the artist's top tracks using get_artist_top_tracks().
  • Finally, it adds the initial track from the playlist, and the artist's top 4 tracks to the newly created playlist using sp.playlist_add_items().

Ideally I would love to take a playlist, for example his favorite "Internet people" and create these playlists for all 100 tracks inside of that playlist ๐Ÿ™‚

However, I am noticing very quickly, that even though I am only testing AND telling my script to take 1 song from 1 playlist, I am running into constant retry-limit problems. Why is this so? And is there anything I am missing or need to fix here in my logic?

Again, thank you so much for taking the time to read this,
- A

 

Reply
4 Replies

Hi whatyoumeanbih, Welcome to the Community!

 

Nice to hear you are also programming with Spotipy.

Could you please insert a code block with what you already have, and I will have a look at it.

You can insert a code block with clicking on the 3 dotsโ€ฆ and then the </> symbol.

XimzendSpotify Star
Help others find this answer and click "Accept as Solution".
If you appreciate my answer, maybe give me a Like.
Note: I'm not a Spotify employee.

Make sure you remove any sensitive information such as the client secret.

XimzendSpotify Star
Help others find this answer and click "Accept as Solution".
If you appreciate my answer, maybe give me a Like.
Note: I'm not a Spotify employee.

Hey thanks for the reply!
Below are some are some of the main parts of the code

# Initialize Spotify API client with cache path
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=SPOTIFY_CLIENT_ID,
                                               client_secret=SPOTIFY_CLIENT_SECRET,
                                               redirect_uri=SPOTIFY_REDIRECT_URI,
                                               scope=SPOTIFY_SCOPE,
                                               cache_path=os.path.join(CACHE_DIR, 'spotify_cache')))

# Initialize Genius API client
genius = lyricsgenius.Genius(GENIUS_CLIENT_ACCESS_TOKEN)

# Function to handle API requests with retry logic for rate limits
def api_request_with_retry(request_func, *args, **kwargs):
    retry_attempts = 5
    for attempt in range(retry_attempts):
        try:
            return request_func(*args, **kwargs)
        except spotipy.exceptions.SpotifyException as e:
            if e.http_status == 429:
                retry_after = int(e.headers.get('Retry-After', 20))
                print(f"Rate limited. Retry after {retry_after} seconds...")
                time.sleep(retry_after)
            else:
                if attempt < retry_attempts - 1:
                    print(f"Error: {e}. Retrying...")
                    time.sleep(2 ** attempt)  # Exponential backoff
                else:
                    print(f"Failed after {retry_attempts} attempts.")
                    raise

# Get the first track from the playlist
playlist_id = '37i9dQZF1DX6OgmB2fwLGd'
results = api_request_with_retry(sp.playlist_tracks, playlist_id, limit=1)
track = results['items'][0]

# Function to fetch lyrics from Genius
def get_lyrics(song_name, artist_name):
    try:
        song = genius.search_song(song_name, artist_name)
        if song:
            lyrics = song.lyrics
            sections = ['[Verse', '[Chorus', '[Hook']
            for section in sections:
                start_index = lyrics.find(section)
                if start_index != -1:
                    end_index = lyrics.find('\n', start_index)
                    if end_index != -1:
                        lyrics_segment = lyrics[end_index:].strip()
                        sanitized_lyrics = sanitize_lyrics(lyrics_segment)
                        return sanitized_lyrics[:300]
            sanitized_lyrics = sanitize_lyrics(lyrics)
            return sanitized_lyrics[:300]
        else:
            return "Lyrics not found"
    except Exception as e:
        print(f"Error fetching lyrics for {song_name} by {artist_name}: {e}")
        return "Lyrics not found"

# Function to get an artist's top tracks
def get_artist_top_tracks(artist_id):
    top_tracks = api_request_with_retry(sp.artist_top_tracks, artist_id)
    return [track['id'] for track in top_tracks['tracks'][:2]]

# Function to upload cover image
def upload_cover_image(playlist_id, image_path, access_token):
    with open(image_path, "rb") as image_file:
        encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
    headers = {
        "Authorization": f"Bearer {access_token}",
        "Content-Type": "image/jpeg"
    }
    url = f"https://api.spotify.com/v1/playlists/{playlist_id}/images"
    response = requests.put(url, headers=headers, data=encoded_string)
    response.raise_for_status()

# Function to create playlist and add songs
def create_playlist_for_song(track, your_song_ids, test_mode=False):
    track_id = track['track']['id']
    track_name = track['track']['name']
    artist_name = track['track']['artists'][0]['name']
    artist_id = track['track']['artists'][0]['id']

    # Step 1: Get lyrics
    lyrics = get_lyrics(track_name, artist_name)
    time.sleep(30)  # 30-second delay

    # Create playlist name
    playlist_name = f"{track_name} {artist_name} / {lyrics[:100]}"  # Adjust character limit as needed

    if test_mode:
        # Save lyrics to a text file for testing
        lyrics_path = os.path.join(LYRICS_DIR, 'testlyrics.txt')
        with open(lyrics_path, 'w') as f:
            f.write(f"Lyrics for {track_name} by {artist_name}:\n{lyrics}")
        print(f"Lyrics saved to {lyrics_path}")
        return

    # Step 2: Create playlist with description
    playlist_description = lyrics[:300]  # Adjust as needed to fit within Spotify's character limit
    playlist = api_request_with_retry(sp.user_playlist_create, user=sp.me()['id'], name=playlist_name, public=True, description=playlist_description)
    print(f"Created playlist: {playlist_name} with ID: {playlist['id']}")
    
    time.sleep(30)  # 30-second delay

    # Step 3: Get cover art
    cover_url = track['track']['album']['images'][0]['url']
    response = requests.get(cover_url)
    img = Image.open(BytesIO(response.content))
    time.sleep(30)  # 30-second delay

    # Step 4: Save cover art locally
    cover_path = os.path.join(COVERS_DIR, f"{track_id}.jpg")
    img.save(cover_path)
    print(f"Cover image saved to {cover_path}")
    time.sleep(30)  # 30-second delay

    # Step 5: Upload cover image to playlist
    upload_cover_image(playlist['id'], cover_path, access_token)
    print(f"Uploaded cover image to playlist: {playlist_name}")
    time.sleep(30)  # 30-second delay

    # Step 6: Get artist's top tracks
    artist_top_tracks = get_artist_top_tracks(artist_id)
    time.sleep(30)  # 30-second delay

    # Step 7: Add songs to playlist
    songs_to_add = [track_id, your_song_ids[0], artist_top_tracks[0], your_song_ids[1], artist_top_tracks[1]]
    api_request_with_retry(sp.playlist_add_items, playlist_id=playlist['id'], items=songs_to_add)
    time.sleep(30)  # 30-second delay

    # Log success
    with open('playlist_creation_log.txt', 'a') as log_file:
        log_file.write(f"Created playlist: {playlist_name} with ID: {playlist['id']}\n")



As far I got it running, it gets stuck at using the lyrics as a description. 300 seems to be to much. I got it running with 5, but not with 250 characters. So, it is a bit trial and error.

XimzendSpotify Star
Help others find this answer and click "Accept as Solution".
If you appreciate my answer, maybe give me a Like.
Note: I'm not a Spotify employee.

Suggested posts

Let's introduce ourselves!

Hey there you, ย  Yeah, you!ย 😁 ย  Welcome - we're glad you joined the Spotify Community! ย  While you here, let's have a fun game and getโ€ฆ

ModeratorStaff / Moderator/ 4 years ago  in Social & Random