Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to create a playlist of every song an artist ID has and appears on (including appears on section)? #702

Closed
greeneryAO opened this issue Jul 2, 2021 · 15 comments
Labels

Comments

@greeneryAO
Copy link

Several apps that claim to do this, like for example alfred spotify mini player that says creates complete collection misses many songs, mostly the appears on sections, which it cannot penetrate, but that is where artists frequently appear on remixes etc.

searching in spotify and sorting by songs is messy too, and often includes junk and songs not by that artist as it runs out of songs by the artist.

Is there a way to run a script that will return a list of all songs if I put in the artist name (ID?), regardless of dupes, just a total list, this would be helpful for grass cutting for updates every few weeks or so, as the big apps that update new releases are annoying and sporadic. I want to do it when I want to do it.

Would it be easy or hard, as you can probably tell I'm not a coder but have some money left on freelancer I'd rather spend than try to claw back.

I think this is the relevant section.

playlist_add_items(playlist_id, items, position=None)
Adds tracks/episodes to a playlist

Parameters:
playlist_id - the id of the playlist
items - a list of track/episode URIs, URLs or IDs
position - the position to add the tracks

thanks.

@kenmacf
Copy link
Contributor

kenmacf commented Jul 2, 2021

I've done something like this, assuming authentication is in place:

spotify_post = spotipy.Spotify(auth=token)

album_track_ids = []
albums = session.spotify_artist_albums(artist_id)
for album in albums:
    if 'US' not in album['available_markets']:
        continue
    for track in session.spotify_album_tracks(album['id']):
        track_artists = [x['uri'] for x in track['artists']]
        if 'spotify:artist:' + artist_id in track_artists:
            album_track_ids.append(track['id'])

playlist_title = 'New Playlist {:%Y-%m-%d %H:%M}'.format(datetime.datetime.today())
new_playlist = spotify_post.user_playlist_create(spotify_userid, playlist_title, public=False)
if spotify_post.playlist_add_items(new_playlist['id'], album_track_ids):
    print(new_playlist['id'])

@greeneryAO
Copy link
Author

greeneryAO commented Jul 2, 2021

thanks very much, I don't know what to make of the code but I'm glad I have it and I have saved it, and it's possible. I will try and learn it on my own, worst case I pay somebody on freelancer who understands python and spotipy

My guy who has helped me before just quit working there, don't want to bug him again, but somebody else could figure it out what I have to put in and where.

I have several python scripts that use authorization and spotipy and work well so I think that's good.

@greeneryAO
Copy link
Author

greeneryAO commented Jul 3, 2021

I've done something like this, assuming authentication is in place:

spotify_post = spotipy.Spotify(auth=token)

album_track_ids = []
albums = session.spotify_artist_albums(artist_id)
for album in albums:
    if 'US' not in album['available_markets']:
        continue
    for track in session.spotify_album_tracks(album['id']):
        track_artists = [x['uri'] for x in track['artists']]
        if 'spotify:artist:' + artist_id in track_artists:
            album_track_ids.append(track['id'])

playlist_title = 'New Playlist {:%Y-%m-%d %H:%M}'.format(datetime.datetime.today())
new_playlist = spotify_post.user_playlist_create(spotify_userid, playlist_title, public=False)
if spotify_post.playlist_add_items(new_playlist['id'], album_track_ids):
    print(new_playlist['id'])

well I looked at it, sorry for not understanding a thing about python but where do you put the artist ID to run the script and generate the playlist?.

I assume I have to add the credentials and the redirect and that on top of the script like is required for spotipy and like is on all my other scripts, but on those scripts there would always be somewhere he would tell me to insert information.

if you could explain I would appreciate, if not , it's cool, I appreciate you even sharing.

@Peter-Schorn
Copy link
Contributor

You must define a variable called artist_id with the artist id.

@greeneryAO
Copy link
Author

greeneryAO commented Jul 3, 2021

would this work?

from pprint import pprint
import spotipy
from spotipy.oauth2 import SpotifyOAuth
from anybar import AnyBar
import threading
# START Custom Credentials
SPOTIPY_CLIENT_ID = 'my private'
SPOTIPY_CLIENT_SECRET = 'my private'
SPOTIFY_USERNAME = 'my private'
# The cache file absolute path
SPOTIFY_CACHE = 'my private'
artist_id = 'I put in here???'

# END Custom Credentials

SPOTIPY_REDIRECT_URI = 'http://127.0.0.1:9090'

sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope, client_id=SPOTIPY_CLIENT_ID,
                                               username=SPOTIFY_USERNAME,
                                               client_secret=SPOTIPY_CLIENT_SECRET, redirect_uri=SPOTIPY_REDIRECT_URI, cache_path=SPOTIFY_CACHE))
album_track_ids = []
albums = session.spotify_artist_albums(artist_id)
for album in albums:
    if 'US' not in album['available_markets']:
        continue
    for track in session.spotify_album_tracks(album['id']):
        track_artists = [x['uri'] for x in track['artists']]
        if 'spotify:artist:' + artist_id in track_artists:
            album_track_ids.append(track['id'])

playlist_title = 'New Playlist {:%Y-%m-%d %H:%M}'.format(datetime.datetime.today())
new_playlist = spotify_post.user_playlist_create(spotify_userid, playlist_title, public=False)
if spotify_post.playlist_add_items(new_playlist['id'], album_track_ids):
    print(new_playlist['id'])

@stephanebruckert
Copy link
Member

@greeneryAO why don't you just run it to know if it would work? it's not that hard, just google how to run a python script and start from there

@greeneryAO
Copy link
Author

greeneryAO commented Jul 3, 2021

I know how to run them, just not to fix them, tried it, error message was

Traceback (most recent call last):
File "spotify playlist maker.py", line 23, in
albums = session.spotify_artist_albums(artist_id)
NameError: name 'session' is not defined

@greeneryAO
Copy link
Author

If I change it around, either the token is not defined, or the session is not defined, or the scope is note defined, must have did something wrong.

@stephanebruckert
Copy link
Member

Yeah session is not defined, as the error message says. @kenmacf's code aims to show the logic but as mentioned it's not including the authentication part. So you will have to adapt it a little.

Since you don't need to add songs to any user playlist, you won't need user authentication, which will be easy for you.

My suggestion is you follow these steps:

  1. Have a look at the Quick Start / Without user authentication example on the README
  2. Run it. If it works, you've already fixed the "session" problem and you can work on the fun stuff 👍
  3. You can now adapt that code to search for artist albums. Instead of sp.search(), you can do sp.artist_albums
  4. Print the result to see what you get
  5. Once you got the albums, get the album tracks with sp.album_tracks

Good luck, and remember to always start from something that works

@greeneryAO
Copy link
Author

greeneryAO commented Jul 3, 2021

thanks, I'll give it a try, what about this code, I found it just in the newest changes to spotipy, maybe it's the same thing.

artist_discography.py

import argparse
import logging

from spotipy.oauth2 import SpotifyClientCredentials
import spotipy
logger = logging.getLogger('examples.artist_discography')
logging.basicConfig(level='INFO')
def get_args():
    parser = argparse.ArgumentParser(description='Shows albums and tracks for '
                                     'given artist')
    parser.add_argument('-a', '--artist', required=True,
                        help='Name of Artist')
    return parser.parse_args()
def get_artist(name):
    results = sp.search(q='artist:' + name, type='artist')
    items = results['artists']['items']
    if len(items) > 0:
        return items[0]

I ran it and it said it succeeded but nothing happened

@stephanebruckert
Copy link
Member

https://github.com/plamere/spotipy/blob/master/examples/artist_discography.py

You skipped the main() function therefore nothing ran. Just run the full thing. Starting with examples is a very good approach

@greeneryAO
Copy link
Author

ran it by itself and error was

spotipy.oauth2.SpotifyOauthError: No client_id. Pass it or set a SPOTIPY_CLIENT_ID environment variable.

ran it with credentials and same error?

#Shows the list of all songs sung by the artist or the band
import argparse
import logging

from spotipy.oauth2 import SpotifyClientCredentials
import spotipy

# START Custom Credentials
SPOTIPY_CLIENT_ID = ''
SPOTIPY_CLIENT_SECRET = ''
SPOTIFY_USERNAME = ''
# The cache file absolute path
SPOTIFY_CACHE = ''

# END Custom Credentials

logger = logging.getLogger('examples.artist_discography')
logging.basicConfig(level='INFO')


def get_args():
    parser = argparse.ArgumentParser(description='Shows albums and tracks for '
                                     'given artist')
    parser.add_argument('-a', '--artist', required=True,
                        help='Name of Artist')
    return parser.parse_args()


def get_artist(name):
    results = sp.search(q='artist:' + name, type='artist')
    items = results['artists']['items']
    if len(items) > 0:
        return items[0]
    else:
        return None


def show_album_tracks(album):
    tracks = []
    results = sp.album_tracks(album['id'])
    tracks.extend(results['items'])
    while results['next']:
        results = sp.next(results)
        tracks.extend(results['items'])
    for i, track in enumerate(tracks):
        logger.info('%s. %s', i+1, track['name'])


def show_artist_albums(artist):
    albums = []
    results = sp.artist_albums(artist['id'], album_type='album')
    albums.extend(results['items'])
    while results['next']:
        results = sp.next(results)
        albums.extend(results['items'])
    logger.info('Total albums: %s', len(albums))
    unique = set()  # skip duplicate albums
    for album in albums:
        name = album['name'].lower()
        if name not in unique:
            logger.info('ALBUM: %s', name)
            unique.add(name)
            show_album_tracks(album)


def show_artist(artist):
    logger.info('====%s====', artist['name'])
    logger.info('Popularity: %s', artist['popularity'])
    if len(artist['genres']) > 0:
        logger.info('Genres: %s', ','.join(artist['genres']))

def main():
    args = get_args()
    artist = get_artist(args.artist)
    show_artist(artist)
    show_artist_albums(artist)


if __name__ == '__main__':
    client_credentials_manager = SpotifyClientCredentials()
    sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
    main()

@stephanebruckert
Copy link
Member

No you didn't pass the credentials. See the difference between your code:

    client_credentials_manager = SpotifyClientCredentials()
    sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)

and the code in the README:

sp = spotipy.Spotify(auth_manager=SpotifyClientCredentials(client_id="YOUR_APP_CLIENT_ID",
                                                           client_secret="YOUR_APP_CLIENT_SECRET"))

@greeneryAO
Copy link
Author

greeneryAO commented Jul 3, 2021

    client_credentials_manager = SpotifyClientCredentials()
    sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)

is in the example, I'll try to make the credentials like the readme

@greeneryAO
Copy link
Author

Tried a bunch of things, putting in my app credentials authorized or not, wouldn't work, same errors.

spotipy.oauth2.SpotifyOauthError: No client_id. Pass it or set a SPOTIPY_CLIENT_ID environment variable.

I know I seem like a dolt to people who know python but not going to start learning python and spotipy for this last script I need for my spotify setup, I guess I'll take both scripts to market and get the dummy version handed to me and see if either can do what I imagined.

thanks anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants