Ejemplo n.º 1
0
def generate_playlist(search: str, sp_user: Spotify, sp_app: Spotify, use_musicmap: bool = False):
    """
    Generates a playlist of top songs of similar artists.
    :param search: the name of the artist. Also supports Spotify URI or ID of the artist when use_musicmap is False
    :param sp_user: a Spotify object authenticated by the user who will be creating the playlist
    :param sp_app: a Spotify object authenticated by the app for a higher rate limit
    :param use_musicmap: True= uses music map for related artists, False = uses Spotify's related artists
    :return: a dict containing information on the playlist or nothing if the process failed.
    """
    uri_prefix = 'spotify:artist:'
    if use_musicmap:
        artist = get_artist(search, sp_user)
        if not artist:
            return False
        track_ids = generate_track_ids_musicmap(artist, sp_user)
    else:
        if search.startswith(uri_prefix) and not use_musicmap:
            artist = sp_user.artist(search)
        else:
            artist = get_artist(search, sp_user)
            print(artist)
        if not artist:
            return "Artist not found"
        track_ids = generate_track_ids_spotify(artist, sp_user)
    if track_ids:
        playlist_name = artist['name'] + " recommendations"
        status = create_and_populate_playlist(playlist_name, track_ids, sp_user)
        print(status)
        if status:
            return status
        else:
            return "Playlist creation failed"
    else:
        print("track_ids is empty")
        return "No similar tracks found"
Ejemplo n.º 2
0
def get_playlist_genres(tracks, suggestion_count):
    # Pagination should happen, at some point above.
    artists_num_appearances = []
    genres = []

    token = sp_oauth.get_cached_token()['access_token']
    sp = Spotify(token)

    # Assemble a list of all artists represented.
    for track in tracks:
        for artist in track['track']['artists']:
            artists_num_appearances.append(artist['id'])
    # Count it
    artists_num_appearances = Counter(artists_num_appearances)

    # Grab the 10 most common artists in the playlist, and get their genres.
    for artist_id, _ in artists_num_appearances.most_common(10):
        artist_info = sp.artist(artist_id)
        for genre in artist_info['genres']:
            genres.append(genre)
    # Count genres
    genre_counter = Counter(genres)

    top_n_genres = genre_counter.most_common(suggestion_count)

    # Resolve these to actual tag objects
    tags = []
    for genre in top_n_genres:
        name = genre[0]
        tag = Tag.objects.get_or_create(name=name, category=TAG_CATEGORY_GENRE)[0]
        tags.append(tag)
        print tag
    return tags
 def get_artist_information(sp_api: Spotify, base_track: dict):
     artist_data: list = []
     try:
         artists: list = base_track['artists']
         artists_obj: list = [
             sp_api.artist(artist.get('id')) for artist in artists
         ]
         artist_data += [
             SpotifyArtistDoc(artist=artist) for artist in artists_obj
         ]
     except Exception as e:
         logger.error(e)
     return artist_data
Ejemplo n.º 4
0
class SpotifyWrapper:
    def __init__(self):
        credentials = SpotifyClientCredentials(
            client_id='d9a2223d179b4d9b845953cdc3b1f49b',
            client_secret='0b2e5ce4a3d345b6a31793c13141b3aa',
        )

        self.spotify = Spotify(client_credentials_manager=credentials)

    def filter(self, artist):
        return {key: artist[key] for key in ('name', 'popularity')}

    def artist(self, n):
        artist = self.spotify.artist(n)

        return self.filter(artist)

    def related_artists(self, n):
        related = self.spotify.artist_related_artists(n)

        for artist in related['artists']:
            yield artist['id'], self.filter(artist)
Ejemplo n.º 5
0
class SpotifyWrapper:
    def __init__(self):
        credentials = SpotifyClientCredentials(
            client_id='25b010562dbf458c80912f82d5eefe15',
            client_secret='ec41140f13124929862f5ba3cb61ccf6',
        )

        self.spotify = Spotify(client_credentials_manager=credentials)

    def filter(self, artist):
        return {key: artist[key] for key in ('name', 'popularity')}

    def artist(self, n):
        artist = self.spotify.artist(n)

        return self.filter(artist)

    def related_artists(self, n):
        related = self.spotify.artist_related_artists(n)

        for artist in related['artists']:
            yield artist['id'], self.filter(artist)
Ejemplo n.º 6
0
class SpotifyWrapper:
    def __init__(self):
        credentials = SpotifyClientCredentials(
            client_id='84c3ea3f396146dba5b4dd15c597a922',
            client_secret='f3e30734460940828047485819f8692f',
        )

        self.spotify = Spotify(client_credentials_manager=credentials)

    def filter(self, artist):
        return {key: artist[key] for key in ('name', 'popularity')}

    def artist(self, n):
        artist = self.spotify.artist(n)

        return self.filter(artist)

    def related_artists(self, n):
        related = self.spotify.artist_related_artists(n)

        for artist in related['artists']:
            yield artist['id'], self.filter(artist)
Ejemplo n.º 7
0
class SpotifyWrapper:
    def __init__(self):
        credentials = SpotifyClientCredentials(
            client_id='SEU CLIENT ID',
            client_secret='SEU CLIENT SECRET',
        )

        self.spotify = Spotify(client_credentials_manager=credentials)

    def filter(self, artist):
        return {key: artist[key] for key in ('name', 'popularity')}

    def artist(self, n):
        artist = self.spotify.artist(n)

        return self.filter(artist)

    def related_artists(self, n):
        related = self.spotify.artist_related_artists(n)

        for artist in related['artists']:
            yield artist['id'], self.filter(artist)
class ClientCredentialsTestSpotipy(unittest.TestCase):
    """
    These tests require user authentication - provide client credentials using the
    following environment variables

    ::

        'SPOTIPY_CLIENT_USERNAME'
        'SPOTIPY_CLIENT_ID'
        'SPOTIPY_CLIENT_SECRET'
        'SPOTIPY_REDIRECT_URI'
    """

    @classmethod
    def setUpClass(self):
        self.spotify = Spotify(client_credentials_manager=SpotifyClientCredentials())
        self.spotify.trace = False

    muse_urn = 'spotify:artist:12Chz98pHFMPJEknJQMWvI'

    def test_request_with_token(self):
        artist = self.spotify.artist(self.muse_urn)
        self.assertTrue(artist['name'] == 'Muse')
Ejemplo n.º 9
0
class TestSpotipy(unittest.TestCase):
    """
    These tests require user authentication - provide client credentials using the
    following environment variables

    ::

        'SPOTIPY_CLIENT_USERNAME'
        'SPOTIPY_CLIENT_ID'
        'SPOTIPY_CLIENT_SECRET'
        'SPOTIPY_REDIRECT_URI'
    """

    creep_urn = 'spotify:track:3HfB5hBU0dmBt8T0iCmH42'
    creep_id = '3HfB5hBU0dmBt8T0iCmH42'
    creep_url = 'http://open.spotify.com/track/3HfB5hBU0dmBt8T0iCmH42'
    el_scorcho_urn = 'spotify:track:0Svkvt5I79wficMFgaqEQJ'
    el_scorcho_bad_urn = 'spotify:track:0Svkvt5I79wficMFgaqEQK'
    pinkerton_urn = 'spotify:album:04xe676vyiTeYNXw15o9jT'
    weezer_urn = 'spotify:artist:3jOstUTkEu2JkjvRdBA5Gu'
    pablo_honey_urn = 'spotify:album:6AZv3m27uyRxi8KyJSfUxL'
    radiohead_urn = 'spotify:artist:4Z8W4fKeB5YxbusRsdQVPb'
    angeles_haydn_urn = 'spotify:album:1vAbqAeuJVWNAe7UR00bdM'

    bad_id = 'BAD_ID'

    @classmethod
    def setUpClass(self):
        missing = list(filter(lambda var: not os.getenv(CCEV[var]), CCEV))

        if missing:
            raise Exception(
                'Please set the client credentials for the test application using the following environment variables: {}'
                .format(CCEV.values()))

        self.username = os.getenv(CCEV['client_username'])

        self.scope = 'user-library-read'

        self.token = prompt_for_user_token(self.username, scope=self.scope)

        self.spotify = Spotify(auth=self.token)

    def test_artist_urn(self):
        artist = self.spotify.artist(self.radiohead_urn)
        self.assertTrue(artist['name'] == 'Radiohead')

    def test_artists(self):
        results = self.spotify.artists([self.weezer_urn, self.radiohead_urn])
        self.assertTrue('artists' in results)
        self.assertTrue(len(results['artists']) == 2)

    def test_album_urn(self):
        album = self.spotify.album(self.pinkerton_urn)
        self.assertTrue(album['name'] == 'Pinkerton')

    def test_album_tracks(self):
        results = self.spotify.album_tracks(self.pinkerton_urn)
        self.assertTrue(len(results['items']) == 10)

    def test_album_tracks_many(self):
        results = self.spotify.album_tracks(self.angeles_haydn_urn)
        tracks = results['items']
        total, received = results['total'], len(tracks)
        while received < total:
            results = self.spotify.album_tracks(self.angeles_haydn_urn,
                                                offset=received)
            tracks.extend(results['items'])
            received = len(tracks)

        self.assertEqual(received, total)

    def test_albums(self):
        results = self.spotify.albums(
            [self.pinkerton_urn, self.pablo_honey_urn])
        self.assertTrue('albums' in results)
        self.assertTrue(len(results['albums']) == 2)

    def test_track_urn(self):
        track = self.spotify.track(self.creep_urn)
        self.assertTrue(track['name'] == 'Creep')

    def test_track_id(self):
        track = self.spotify.track(self.creep_id)
        self.assertTrue(track['name'] == 'Creep')

    def test_track_url(self):
        track = self.spotify.track(self.creep_url)
        self.assertTrue(track['name'] == 'Creep')

    def test_track_bad_urn(self):
        try:
            track = self.spotify.track(self.el_scorcho_bad_urn)
            self.assertTrue(False)
        except SpotifyException:
            self.assertTrue(True)

    def test_tracks(self):
        results = self.spotify.tracks([self.creep_url, self.el_scorcho_urn])
        self.assertTrue('tracks' in results)
        self.assertTrue(len(results['tracks']) == 2)

    def test_artist_top_tracks(self):
        results = self.spotify.artist_top_tracks(self.weezer_urn)
        self.assertTrue('tracks' in results)
        self.assertTrue(len(results['tracks']) == 10)

    def test_artist_related_artists(self):
        results = self.spotify.artist_related_artists(self.weezer_urn)
        self.assertTrue('artists' in results)
        self.assertTrue(len(results['artists']) == 20)
        for artist in results['artists']:
            if artist['name'] == 'Jimmy Eat World':
                found = True
        self.assertTrue(found)

    def test_artist_search(self):
        results = self.spotify.search(q='weezer', type='artist')
        self.assertTrue('artists' in results)
        self.assertTrue(len(results['artists']['items']) > 0)
        self.assertTrue(results['artists']['items'][0]['name'] == 'Weezer')

    def test_artist_search_with_market(self):
        results = self.spotify.search(q='weezer', type='artist', market='GB')
        self.assertTrue('artists' in results)
        self.assertTrue(len(results['artists']['items']) > 0)
        self.assertTrue(results['artists']['items'][0]['name'] == 'Weezer')

    def test_artist_albums(self):
        results = self.spotify.artist_albums(self.weezer_urn)
        self.assertTrue('items' in results)
        self.assertTrue(len(results['items']) > 0)

        found = False
        for album in results['items']:
            if album['name'] == 'Hurley':
                found = True

        self.assertTrue(found)

    def test_search_timeout(self):
        sp = Spotify(auth=self.token, requests_timeout=.01)
        try:
            results = sp.search(q='my*', type='track')
            self.assertTrue(False, 'unexpected search timeout')
        except requests.Timeout:
            self.assertTrue(True, 'expected search timeout')

    def test_album_search(self):
        results = self.spotify.search(q='weezer pinkerton', type='album')
        self.assertTrue('albums' in results)
        self.assertTrue(len(results['albums']['items']) > 0)
        self.assertTrue(
            results['albums']['items'][0]['name'].find('Pinkerton') >= 0)

    def test_track_search(self):
        results = self.spotify.search(q='el scorcho weezer', type='track')
        self.assertTrue('tracks' in results)
        self.assertTrue(len(results['tracks']['items']) > 0)
        self.assertTrue(results['tracks']['items'][0]['name'] == 'El Scorcho')

    def test_user(self):
        user = self.spotify.user(user='******')
        self.assertTrue(user['uri'] == 'spotify:user:plamere')

    def test_track_bad_id(self):
        try:
            track = self.spotify.track(self.bad_id)
            self.assertTrue(False)
        except SpotifyException:
            self.assertTrue(True)

    def test_track_bad_id(self):
        try:
            track = self.spotify.track(self.bad_id)
            self.assertTrue(False)
        except SpotifyException:
            self.assertTrue(True)

    def test_unauthenticated_post_fails(self):
        with self.assertRaises(SpotifyException) as cm:
            self.spotify.user_playlist_create("spotify",
                                              "Best hits of the 90s")
        self.assertTrue(cm.exception.http_status == 401
                        or cm.exception.http_status == 403)

    def test_custom_requests_session(self):
        sess = requests.Session()
        sess.headers["user-agent"] = "spotipy-test"
        with_custom_session = Spotify(auth=self.token, requests_session=sess)
        self.assertTrue(
            with_custom_session.user(user="******")["uri"] == "spotify:user:akx")

    def test_force_no_requests_session(self):
        with_no_session = Spotify(auth=self.token, requests_session=False)
        self.assertFalse(isinstance(with_no_session._session,
                                    requests.Session))
        self.assertTrue(
            with_no_session.user(user="******")["uri"] == "spotify:user:akx")
Ejemplo n.º 10
0
class AuthTestSpotipy(unittest.TestCase):
    """
    These tests require client authentication - provide client credentials
    using the following environment variables

    ::

        'SPOTIPY_CLIENT_ID'
        'SPOTIPY_CLIENT_SECRET'
    """

    playlist = "spotify:user:plamere:playlist:2oCEWyyAPbZp9xhVSxZavx"
    four_tracks = [
        "spotify:track:6RtPijgfPKROxEzTHNRiDp",
        "spotify:track:7IHOIqZUUInxjVkko181PB", "4VrWlk8IQxevMvERoX08iC",
        "http://open.spotify.com/track/3cySlItpiPiIAzU3NyHCJf"
    ]

    two_tracks = [
        "spotify:track:6RtPijgfPKROxEzTHNRiDp",
        "spotify:track:7IHOIqZUUInxjVkko181PB"
    ]

    other_tracks = [
        "spotify:track:2wySlB6vMzCbQrRnNGOYKa",
        "spotify:track:29xKs5BAHlmlX1u4gzQAbJ",
        "spotify:track:1PB7gRWcvefzu7t3LJLUlf"
    ]

    bad_id = 'BAD_ID'

    creep_urn = 'spotify:track:6b2oQwSGFkzsMtQruIWm2p'
    creep_id = '6b2oQwSGFkzsMtQruIWm2p'
    creep_url = 'http://open.spotify.com/track/6b2oQwSGFkzsMtQruIWm2p'
    el_scorcho_urn = 'spotify:track:0Svkvt5I79wficMFgaqEQJ'
    el_scorcho_bad_urn = 'spotify:track:0Svkvt5I79wficMFgaqEQK'
    pinkerton_urn = 'spotify:album:04xe676vyiTeYNXw15o9jT'
    weezer_urn = 'spotify:artist:3jOstUTkEu2JkjvRdBA5Gu'
    pablo_honey_urn = 'spotify:album:6AZv3m27uyRxi8KyJSfUxL'
    radiohead_urn = 'spotify:artist:4Z8W4fKeB5YxbusRsdQVPb'
    angeles_haydn_urn = 'spotify:album:1vAbqAeuJVWNAe7UR00bdM'
    heavyweight_urn = 'spotify:show:5c26B28vZMN8PG0Nppmn5G'
    heavyweight_id = '5c26B28vZMN8PG0Nppmn5G'
    heavyweight_url = 'https://open.spotify.com/show/5c26B28vZMN8PG0Nppmn5G'
    reply_all_urn = 'spotify:show:7gozmLqbcbr6PScMjc0Zl4'
    heavyweight_ep1_urn = 'spotify:episode:68kq3bNz6hEuq8NtdfwERG'
    heavyweight_ep1_id = '68kq3bNz6hEuq8NtdfwERG'
    heavyweight_ep1_url = 'https://open.spotify.com/episode/68kq3bNz6hEuq8NtdfwERG'
    reply_all_ep1_urn = 'spotify:episode:1KHjbpnmNpFmNTczQmTZlR'

    @classmethod
    def setUpClass(self):
        self.spotify = Spotify(
            client_credentials_manager=SpotifyClientCredentials())
        self.spotify.trace = False

    def test_audio_analysis(self):
        result = self.spotify.audio_analysis(self.four_tracks[0])
        assert ('beats' in result)

    def test_audio_features(self):
        results = self.spotify.audio_features(self.four_tracks)
        self.assertTrue(len(results) == len(self.four_tracks))
        for track in results:
            assert ('speechiness' in track)

    def test_audio_features_with_bad_track(self):
        bad_tracks = ['spotify:track:bad']
        input = self.four_tracks + bad_tracks
        results = self.spotify.audio_features(input)
        self.assertTrue(len(results) == len(input))
        for track in results[:-1]:
            if track is not None:
                assert ('speechiness' in track)
        self.assertTrue(results[-1] is None)

    def test_recommendations(self):
        results = self.spotify.recommendations(seed_tracks=self.four_tracks,
                                               min_danceability=0,
                                               max_loudness=0,
                                               target_popularity=50)
        self.assertTrue(len(results['tracks']) == 20)

    def test_artist_urn(self):
        artist = self.spotify.artist(self.radiohead_urn)
        self.assertTrue(artist['name'] == 'Radiohead')

    def test_artists(self):
        results = self.spotify.artists([self.weezer_urn, self.radiohead_urn])
        self.assertTrue('artists' in results)
        self.assertTrue(len(results['artists']) == 2)

    def test_album_urn(self):
        album = self.spotify.album(self.pinkerton_urn)
        self.assertTrue(album['name'] == 'Pinkerton')

    def test_album_tracks(self):
        results = self.spotify.album_tracks(self.pinkerton_urn)
        self.assertTrue(len(results['items']) == 10)

    def test_album_tracks_many(self):
        results = self.spotify.album_tracks(self.angeles_haydn_urn)
        tracks = results['items']
        total, received = results['total'], len(tracks)
        while received < total:
            results = self.spotify.album_tracks(self.angeles_haydn_urn,
                                                offset=received)
            tracks.extend(results['items'])
            received = len(tracks)

        self.assertEqual(received, total)

    def test_albums(self):
        results = self.spotify.albums(
            [self.pinkerton_urn, self.pablo_honey_urn])
        self.assertTrue('albums' in results)
        self.assertTrue(len(results['albums']) == 2)

    def test_track_urn(self):
        track = self.spotify.track(self.creep_urn)
        self.assertTrue(track['name'] == 'Creep')

    def test_track_id(self):
        track = self.spotify.track(self.creep_id)
        self.assertTrue(track['name'] == 'Creep')
        self.assertTrue(track['popularity'] > 0)

    def test_track_url(self):
        track = self.spotify.track(self.creep_url)
        self.assertTrue(track['name'] == 'Creep')

    def test_track_bad_urn(self):
        try:
            self.spotify.track(self.el_scorcho_bad_urn)
            self.assertTrue(False)
        except SpotifyException:
            self.assertTrue(True)

    def test_tracks(self):
        results = self.spotify.tracks([self.creep_url, self.el_scorcho_urn])
        self.assertTrue('tracks' in results)
        self.assertTrue(len(results['tracks']) == 2)

    def test_artist_top_tracks(self):
        results = self.spotify.artist_top_tracks(self.weezer_urn)
        self.assertTrue('tracks' in results)
        self.assertTrue(len(results['tracks']) == 10)

    def test_artist_related_artists(self):
        results = self.spotify.artist_related_artists(self.weezer_urn)
        self.assertTrue('artists' in results)
        self.assertTrue(len(results['artists']) == 20)
        for artist in results['artists']:
            if artist['name'] == 'Jimmy Eat World':
                found = True
        self.assertTrue(found)

    def test_artist_search(self):
        results = self.spotify.search(q='weezer', type='artist')
        self.assertTrue('artists' in results)
        self.assertTrue(len(results['artists']['items']) > 0)
        self.assertTrue(results['artists']['items'][0]['name'] == 'Weezer')

    def test_artist_search_with_market(self):
        results = self.spotify.search(q='weezer', type='artist', market='GB')
        self.assertTrue('artists' in results)
        self.assertTrue(len(results['artists']['items']) > 0)
        self.assertTrue(results['artists']['items'][0]['name'] == 'Weezer')

    def test_artist_search_with_multiple_markets(self):
        total = 5
        countries_list = ['GB', 'US', 'AU']
        countries_tuple = ('GB', 'US', 'AU')

        results_multiple = self.spotify.search_markets(q='weezer',
                                                       type='artist',
                                                       markets=countries_list)
        results_all = self.spotify.search_markets(q='weezer', type='artist')
        results_tuple = self.spotify.search_markets(q='weezer',
                                                    type='artist',
                                                    markets=countries_tuple)
        results_limited = self.spotify.search_markets(q='weezer',
                                                      limit=3,
                                                      type='artist',
                                                      markets=countries_list,
                                                      total=total)

        self.assertTrue(
            all('artists' in results_multiple[country]
                for country in results_multiple))
        self.assertTrue(
            all('artists' in results_all[country] for country in results_all))
        self.assertTrue(
            all('artists' in results_tuple[country]
                for country in results_tuple))
        self.assertTrue(
            all('artists' in results_limited[country]
                for country in results_limited))

        self.assertTrue(
            all(
                len(results_multiple[country]['artists']['items']) > 0
                for country in results_multiple))
        self.assertTrue(
            all(
                len(results_all[country]['artists']['items']) > 0
                for country in results_all))
        self.assertTrue(
            all(
                len(results_tuple[country]['artists']['items']) > 0
                for country in results_tuple))
        self.assertTrue(
            all(
                len(results_limited[country]['artists']['items']) > 0
                for country in results_limited))

        self.assertTrue(
            all(results_multiple[country]['artists']['items'][0]['name'] ==
                'Weezer' for country in results_multiple))
        self.assertTrue(
            all(results_all[country]['artists']['items'][0]['name'] == 'Weezer'
                for country in results_all))
        self.assertTrue(
            all(results_tuple[country]['artists']['items'][0]['name'] ==
                'Weezer' for country in results_tuple))
        self.assertTrue(
            all(results_limited[country]['artists']['items'][0]['name'] ==
                'Weezer' for country in results_limited))

        total_limited_results = 0
        for country in results_limited:
            total_limited_results += len(
                results_limited[country]['artists']['items'])
        self.assertTrue(total_limited_results <= total)

    def test_artist_albums(self):
        results = self.spotify.artist_albums(self.weezer_urn)
        self.assertTrue('items' in results)
        self.assertTrue(len(results['items']) > 0)

        found = False
        for album in results['items']:
            if album['name'] == 'Hurley':
                found = True

        self.assertTrue(found)

    def test_search_timeout(self):
        client_credentials_manager = SpotifyClientCredentials()
        sp = spotipy.Spotify(
            requests_timeout=0.01,
            client_credentials_manager=client_credentials_manager)

        # depending on the timing or bandwidth, this raises a timeout or connection error"
        self.assertRaises(
            (requests.exceptions.Timeout, requests.exceptions.ConnectionError),
            lambda: sp.search(q='my*', type='track'))

    def test_album_search(self):
        results = self.spotify.search(q='weezer pinkerton', type='album')
        self.assertTrue('albums' in results)
        self.assertTrue(len(results['albums']['items']) > 0)
        self.assertTrue(
            results['albums']['items'][0]['name'].find('Pinkerton') >= 0)

    def test_track_search(self):
        results = self.spotify.search(q='el scorcho weezer', type='track')
        self.assertTrue('tracks' in results)
        self.assertTrue(len(results['tracks']['items']) > 0)
        self.assertTrue(results['tracks']['items'][0]['name'] == 'El Scorcho')

    def test_user(self):
        user = self.spotify.user(user='******')
        self.assertTrue(user['uri'] == 'spotify:user:plamere')

    def test_track_bad_id(self):
        try:
            self.spotify.track(self.bad_id)
            self.assertTrue(False)
        except SpotifyException:
            self.assertTrue(True)

    def test_show_urn(self):
        show = self.spotify.show(self.heavyweight_urn, market="US")
        self.assertTrue(show['name'] == 'Heavyweight')

    def test_show_id(self):
        show = self.spotify.show(self.heavyweight_id, market="US")
        self.assertTrue(show['name'] == 'Heavyweight')

    def test_show_url(self):
        show = self.spotify.show(self.heavyweight_url, market="US")
        self.assertTrue(show['name'] == 'Heavyweight')

    def test_show_bad_urn(self):
        with self.assertRaises(SpotifyException):
            self.spotify.show("bogus_urn", market="US")

    def test_shows(self):
        results = self.spotify.shows(
            [self.heavyweight_urn, self.reply_all_urn], market="US")
        self.assertTrue('shows' in results)
        self.assertTrue(len(results['shows']) == 2)

    def test_show_episodes(self):
        results = self.spotify.show_episodes(self.heavyweight_urn, market="US")
        self.assertTrue(len(results['items']) > 1)

    def test_show_episodes_many(self):
        results = self.spotify.show_episodes(self.reply_all_urn, market="US")
        episodes = results['items']
        total, received = results['total'], len(episodes)
        while received < total:
            results = self.spotify.show_episodes(self.reply_all_urn,
                                                 offset=received,
                                                 market="US")
            episodes.extend(results['items'])
            received = len(episodes)

        self.assertEqual(received, total)

    def test_episode_urn(self):
        episode = self.spotify.episode(self.heavyweight_ep1_urn, market="US")
        self.assertTrue(episode['name'] == '#1 Buzz')

    def test_episode_id(self):
        episode = self.spotify.episode(self.heavyweight_ep1_id, market="US")
        self.assertTrue(episode['name'] == '#1 Buzz')

    def test_episode_url(self):
        episode = self.spotify.episode(self.heavyweight_ep1_url, market="US")
        self.assertTrue(episode['name'] == '#1 Buzz')

    def test_episode_bad_urn(self):
        with self.assertRaises(SpotifyException):
            self.spotify.episode("bogus_urn", market="US")

    def test_episodes(self):
        results = self.spotify.episodes(
            [self.heavyweight_ep1_urn, self.reply_all_ep1_urn], market="US")
        self.assertTrue('episodes' in results)
        self.assertTrue(len(results['episodes']) == 2)

    def test_unauthenticated_post_fails(self):
        with self.assertRaises(SpotifyException) as cm:
            self.spotify.user_playlist_create("spotify",
                                              "Best hits of the 90s")
        self.assertTrue(cm.exception.http_status == 401
                        or cm.exception.http_status == 403)

    def test_custom_requests_session(self):
        sess = requests.Session()
        sess.headers["user-agent"] = "spotipy-test"
        with_custom_session = spotipy.Spotify(
            client_credentials_manager=SpotifyClientCredentials(),
            requests_session=sess)
        self.assertTrue(
            with_custom_session.user(user="******")["uri"] == "spotify:user:akx")
        sess.close()

    def test_force_no_requests_session(self):
        with_no_session = spotipy.Spotify(
            client_credentials_manager=SpotifyClientCredentials(),
            requests_session=False)
        self.assertNotIsInstance(with_no_session._session, requests.Session)
        user = with_no_session.user(user="******")
        self.assertEqual(user["uri"], "spotify:user:akx")
Ejemplo n.º 11
0
    async def spotify(self, ctx: Context, url: str = None, type_: str = None):
        if not url:
            return await ctx.send(embed=ErrorEmbed(
                author=ctx.author,
                title=':x: Missing Spotify link or ID'
            ))
        elif not type_:
            try:
                type_ = url.split('&')[0].split('?')[0].split('/')[3]
            except IndexError:
                pass

        if type_ == 'user':
            return await ctx.send(embed=ErrorEmbed(
                author=ctx.author,
                title=':x: User profiles are not supported',
                description='...yet?'
            ))
        elif type_ not in ['track', 'album', 'artist', 'playlist']:
            return await ctx.send(embed=ErrorEmbed(
                author=ctx.author,
                title=':x: What is this?',
                description='Is it `track`, `album`, `artist` or `playlist`?'
            ))

        if url.startswith(('http://open.spotify.com', 'https://open.spotify.com')):
            url = url.split('?')[0].split('/')[-1]

        type_ = type_.lower()

        try:
            sp = Spotify(auth_manager=SpotifyClientCredentials(
                client_id=spotify_client_id(),
                client_secret=spotify_client_secret()
            ))
        except SpotifyOauthError:
            sp = None

        if not sp:
            return await ctx.send(embed=ErrorEmbed(
                author=ctx.author,
                title=':x: Unable to connect to Spotify!'
            ))

        result = error_code = None
        em = SuccessEmbed(
            author=ctx.author
        ).set_author(
            name=f'{ctx.author.display_name} shared a{"n" if type_[0] == "a" else ""} {type_}:',
            icon_url=ctx.author.avatar_url
        )

        if type_ == 'track':
            try:
                result = sp.track(url)
            except SpotifyException as e:
                error_code = int(e.http_status)
        elif type_ == 'album':
            try:
                result = sp.album(url)
            except SpotifyException as e:
                error_code = int(e.http_status)
        elif type_ == 'playlist':
            try:
                result = sp.playlist(url)
            except SpotifyException as e:
                error_code = int(e.http_status)
        elif type_ == 'artist':
            try:
                result = sp.artist(url)
            except SpotifyException as e:
                error_code = int(e.http_status)
        else:
            return await ctx.send(embed=ErrorEmbed(
                author=ctx.author,
                title=':x: Unknown object type',
                description='Check `>help` for valid object types.'
            ))

        if error_code:
            if error_code == 400:
                d = 'Invalid ID or URL.'
            elif error_code == 429:
                d = 'Unable to do that now, please try again in 5 minutes.'
            elif str(error_code).startswith('5'):
                d = 'Spotify is not responding.'
            else:
                d = 'Unknown error. Please try again in a few minutes and please make sure URL or ID is valid.'
            return await ctx.send(embed=ErrorEmbed(
                author=ctx.author,
                title=':x: An error occurred!',
                description=d
            ))
        elif not result:
            return await ctx.send(embed=ErrorEmbed(
                author=ctx.author,
                title=':x: Unable to find anything on Spotify',
                description='Probably URL/ID is wrong.'
            ))

        title = result['name']

        # Artists
        if type_ not in ['artist', 'playlist']:
            artists = list(map(lambda x: [x['name'], x['external_urls']['spotify']], result['artists']))
        elif type_ in ['playlist']:
            artists = [[result['owner']['display_name'], result['owner']['external_urls']['spotify']]]
        else:
            artists = None

        # Released
        if type_ == 'track':
            released = result['album']['release_date']
        elif type_ == 'album':
            released = result['release_date']
        else:
            released = None

        # Genres
        if type_ in ['artist', 'album']:
            genres = ', '.join(result['genres']) or 'Not specified'
        else:
            genres = None

        ex_url = result['external_urls']['spotify']
        thumbnail = result['album']['images'][0]['url'] if type_ == 'track' else result['images'][0]['url']

        # Title
        if title:
            em.add_field(
                name='Name' if type_ in ['artist'] else 'Title',
                value=title
            )

        # Author / Artist(s)
        if artists:
            em.add_field(
                name='Author' if type_ == 'playlist' else 'Artist' if len(artists) == 1 else 'Artists',
                value=', '.join(map(lambda x: f'[{x[0]}]({x[1]} "Check it on Spotify")', artists))
            )

        # Followers
        if type_ in ['artist', 'playlist']:
            em.add_field(
                name='Followers',
                value=result['followers']['total']
            )

        # Album
        if type_ == 'track':
            em.add_field(
                name='Album',
                value=f'[{result["name"]}]({result["album"]["external_urls"]["spotify"]} "Check it on Spotify")'
            )

        # Released
        if released:
            em.add_field(
                name='Released',
                value=released
            )

        # Tracks
        if type_ in ['playlist', 'album']:
            em.add_field(
                name='Tracks',
                value=str(result['tracks']['total'])
            )

        # Genres
        if genres:
            em.add_field(
                name='Genres',
                value=genres
            )

        # Popularity
        if type_ in ['track', 'artist', 'album']:
            em.add_field(
                name='Popularity',
                value=str(result['popularity'])
            )

        # Label
        elif type_ == 'album':
            em.add_field(
                name='Label',
                value=result['label']
            )

        # Spotify link
        if ex_url:
            em.add_field(
                name='Spotify',
                value=ex_url,
                inline=False
            )

        # YouTube link
        if type_ == 'track':
            # Lookup YouTube
            query = '{} {}'.format(result['name'], ' '.join(map(lambda x: x['name'], result['artists'])))
            yt = SearchVideos(
                query,
                mode='dict',
                max_results=1
            ).result()
            # noinspection PyTypeChecker
            yt = yt['search_result'][0]['link'] if yt else None
            em.add_field(
                name='YouTube',
                value=yt,
                inline=False
            )

        # Thumbnail
        if thumbnail:
            em.set_thumbnail(
                url=thumbnail
            )

        await ctx.send(embed=em)

        try:
            await ctx.message.delete()
        except Forbidden or NotFound or HTTPException:
            pass
Ejemplo n.º 12
0
class AuthTestSpotipy(unittest.TestCase):
    """
    These tests require client authentication - provide client credentials
    using the following environment variables

    ::

        'SPOTIPY_CLIENT_ID'
        'SPOTIPY_CLIENT_SECRET'
    """

    playlist = "spotify:user:plamere:playlist:2oCEWyyAPbZp9xhVSxZavx"
    four_tracks = [
        "spotify:track:6RtPijgfPKROxEzTHNRiDp",
        "spotify:track:7IHOIqZUUInxjVkko181PB", "4VrWlk8IQxevMvERoX08iC",
        "http://open.spotify.com/track/3cySlItpiPiIAzU3NyHCJf"
    ]

    two_tracks = [
        "spotify:track:6RtPijgfPKROxEzTHNRiDp",
        "spotify:track:7IHOIqZUUInxjVkko181PB"
    ]

    other_tracks = [
        "spotify:track:2wySlB6vMzCbQrRnNGOYKa",
        "spotify:track:29xKs5BAHlmlX1u4gzQAbJ",
        "spotify:track:1PB7gRWcvefzu7t3LJLUlf"
    ]

    bad_id = 'BAD_ID'

    creep_urn = 'spotify:track:3HfB5hBU0dmBt8T0iCmH42'
    creep_id = '3HfB5hBU0dmBt8T0iCmH42'
    creep_url = 'http://open.spotify.com/track/3HfB5hBU0dmBt8T0iCmH42'
    el_scorcho_urn = 'spotify:track:0Svkvt5I79wficMFgaqEQJ'
    el_scorcho_bad_urn = 'spotify:track:0Svkvt5I79wficMFgaqEQK'
    pinkerton_urn = 'spotify:album:04xe676vyiTeYNXw15o9jT'
    weezer_urn = 'spotify:artist:3jOstUTkEu2JkjvRdBA5Gu'
    pablo_honey_urn = 'spotify:album:6AZv3m27uyRxi8KyJSfUxL'
    radiohead_urn = 'spotify:artist:4Z8W4fKeB5YxbusRsdQVPb'
    angeles_haydn_urn = 'spotify:album:1vAbqAeuJVWNAe7UR00bdM'

    @classmethod
    def setUpClass(self):
        self.spotify = Spotify(
            client_credentials_manager=SpotifyClientCredentials())
        self.spotify.trace = False

    def test_audio_analysis(self):
        result = self.spotify.audio_analysis(self.four_tracks[0])
        assert ('beats' in result)

    def test_audio_features(self):
        results = self.spotify.audio_features(self.four_tracks)
        self.assertTrue(len(results) == len(self.four_tracks))
        for track in results:
            assert ('speechiness' in track)

    def test_audio_features_with_bad_track(self):
        bad_tracks = ['spotify:track:bad']
        input = self.four_tracks + bad_tracks
        results = self.spotify.audio_features(input)
        self.assertTrue(len(results) == len(input))
        for track in results[:-1]:
            if track is not None:
                assert ('speechiness' in track)
        self.assertTrue(results[-1] is None)

    def test_recommendations(self):
        results = self.spotify.recommendations(seed_tracks=self.four_tracks,
                                               min_danceability=0,
                                               max_loudness=0,
                                               target_popularity=50)
        self.assertTrue(len(results['tracks']) == 20)

    def test_artist_urn(self):
        artist = self.spotify.artist(self.radiohead_urn)
        self.assertTrue(artist['name'] == 'Radiohead')

    def test_artists(self):
        results = self.spotify.artists([self.weezer_urn, self.radiohead_urn])
        self.assertTrue('artists' in results)
        self.assertTrue(len(results['artists']) == 2)

    def test_album_urn(self):
        album = self.spotify.album(self.pinkerton_urn)
        self.assertTrue(album['name'] == 'Pinkerton')

    def test_album_tracks(self):
        results = self.spotify.album_tracks(self.pinkerton_urn)
        self.assertTrue(len(results['items']) == 10)

    def test_album_tracks_many(self):
        results = self.spotify.album_tracks(self.angeles_haydn_urn)
        tracks = results['items']
        total, received = results['total'], len(tracks)
        while received < total:
            results = self.spotify.album_tracks(self.angeles_haydn_urn,
                                                offset=received)
            tracks.extend(results['items'])
            received = len(tracks)

        self.assertEqual(received, total)

    def test_albums(self):
        results = self.spotify.albums(
            [self.pinkerton_urn, self.pablo_honey_urn])
        self.assertTrue('albums' in results)
        self.assertTrue(len(results['albums']) == 2)

    def test_track_urn(self):
        track = self.spotify.track(self.creep_urn)
        self.assertTrue(track['name'] == 'Creep')

    def test_track_id(self):
        track = self.spotify.track(self.creep_id)
        self.assertTrue(track['name'] == 'Creep')
        self.assertTrue(track['popularity'] > 0)

    def test_track_url(self):
        track = self.spotify.track(self.creep_url)
        self.assertTrue(track['name'] == 'Creep')

    def test_track_bad_urn(self):
        try:
            self.spotify.track(self.el_scorcho_bad_urn)
            self.assertTrue(False)
        except SpotifyException:
            self.assertTrue(True)

    def test_tracks(self):
        results = self.spotify.tracks([self.creep_url, self.el_scorcho_urn])
        self.assertTrue('tracks' in results)
        self.assertTrue(len(results['tracks']) == 2)

    def test_artist_top_tracks(self):
        results = self.spotify.artist_top_tracks(self.weezer_urn)
        self.assertTrue('tracks' in results)
        self.assertTrue(len(results['tracks']) == 10)

    def test_artist_related_artists(self):
        results = self.spotify.artist_related_artists(self.weezer_urn)
        self.assertTrue('artists' in results)
        self.assertTrue(len(results['artists']) == 20)
        for artist in results['artists']:
            if artist['name'] == 'Jimmy Eat World':
                found = True
        self.assertTrue(found)

    def test_artist_search(self):
        results = self.spotify.search(q='weezer', type='artist')
        self.assertTrue('artists' in results)
        self.assertTrue(len(results['artists']['items']) > 0)
        self.assertTrue(results['artists']['items'][0]['name'] == 'Weezer')

    def test_artist_search_with_market(self):
        results = self.spotify.search(q='weezer', type='artist', market='GB')
        self.assertTrue('artists' in results)
        self.assertTrue(len(results['artists']['items']) > 0)
        self.assertTrue(results['artists']['items'][0]['name'] == 'Weezer')

    def test_artist_albums(self):
        results = self.spotify.artist_albums(self.weezer_urn)
        self.assertTrue('items' in results)
        self.assertTrue(len(results['items']) > 0)

        found = False
        for album in results['items']:
            if album['name'] == 'Hurley':
                found = True

        self.assertTrue(found)

    def test_search_timeout(self):
        client_credentials_manager = SpotifyClientCredentials()
        sp = spotipy.Spotify(
            client_credentials_manager=client_credentials_manager,
            requests_timeout=.01)

        try:
            sp.search(q='my*', type='track')
            self.assertTrue(False, 'unexpected search timeout')
        except requests.exceptions.Timeout:
            self.assertTrue(True, 'expected search timeout')

    def test_album_search(self):
        results = self.spotify.search(q='weezer pinkerton', type='album')
        self.assertTrue('albums' in results)
        self.assertTrue(len(results['albums']['items']) > 0)
        self.assertTrue(
            results['albums']['items'][0]['name'].find('Pinkerton') >= 0)

    def test_track_search(self):
        results = self.spotify.search(q='el scorcho weezer', type='track')
        self.assertTrue('tracks' in results)
        self.assertTrue(len(results['tracks']['items']) > 0)
        self.assertTrue(results['tracks']['items'][0]['name'] == 'El Scorcho')

    def test_user(self):
        user = self.spotify.user(user='******')
        self.assertTrue(user['uri'] == 'spotify:user:plamere')

    def test_track_bad_id(self):
        try:
            self.spotify.track(self.bad_id)
            self.assertTrue(False)
        except SpotifyException:
            self.assertTrue(True)

    def test_unauthenticated_post_fails(self):
        with self.assertRaises(SpotifyException) as cm:
            self.spotify.user_playlist_create("spotify",
                                              "Best hits of the 90s")
        self.assertTrue(cm.exception.http_status == 401
                        or cm.exception.http_status == 403)

    def test_custom_requests_session(self):
        sess = requests.Session()
        sess.headers["user-agent"] = "spotipy-test"
        with_custom_session = spotipy.Spotify(
            client_credentials_manager=SpotifyClientCredentials(),
            requests_session=sess)
        self.assertTrue(
            with_custom_session.user(user="******")["uri"] == "spotify:user:akx")
        sess.close()

    def test_force_no_requests_session(self):
        from requests import Session
        with_no_session = spotipy.Spotify(
            client_credentials_manager=SpotifyClientCredentials(),
            requests_session=False)
        self.assertFalse(isinstance(with_no_session._session, Session))
        self.assertTrue(
            with_no_session.user(user="******")["uri"] == "spotify:user:akx")
Ejemplo n.º 13
0
def get_artist(sp: Spotify, artist_id: str) -> Dict[str, Any]:
    """Returns an artist given its ID or URI"""
    return sp.artist(artist_id)
Ejemplo n.º 14
0
class Ingestor():
    def __init__(self,
                 client_id=None,
                 client_secret=None,
                 dbURl=None,
                 db_user=None,
                 db_password=None):

        # spotipy Client flow
        if client_id is None:
            client_id = CLIENT_ID
        if client_secret is None:
            client_secret = CLIENT_SECRET

        self.client_id = client_id
        self.client_secret = client_secret
        self.client_creds = SpotifyClientCredentials(
            client_id=self.client_id, client_secret=self.client_secret)

        # creeate spotipy client
        self.spotipy = Spotify(auth=self.client_creds.get_access_token())

        self.connector = DBConnector()

    def ingest(self):

        self.ingest_categories()

    def get_artist_by_name(self, name):
        """Retrives a list of artist obecjts based on searching for the artist
        name"""

        q = 'artist:' + name
        return self.spotipy.search(q,
                                   limit=10,
                                   offset=0,
                                   type='artist',
                                   market=None)['artists']['items']

    def ingest_related_artist(self,
                              artist_id,
                              limit=NUM_REL_ARTISTS,
                              _depth=0):
        """Recursively ingest artist related to a specific artist.
            Artist must already be in DB."""

        # TODO: check if artist DNE and insert if so

        self.connector.update_artist(artist_id, 'ingested', 'true')

        ara = self.spotipy.artist_related_artists(artist_id)

        for i, a in enumerate(ara['artists']):
            if i > limit:
                break

            self.connector.insert_artist(a)
            self.connector.insert_related_relation(artist_id, a['id'])

            if _depth > 0:
                self.ingest_related_artist(a['id'], _depth - 1)

    def ingest_by_name(self, name):
        """Ingests the first artist from the search of on artist by name into
        the database"""

        res = self.get_artist_by_name(name)[0]
        self.connector.insert_artist(res)

    def ingest_by_id(self, artist_id):
        """Ingest artist by id"""

        res = self.spotipy.artist(artist_id)
        self.connector.insert_artist(res)

    def ingest_categories(self):
        """Ingest categories from spotifies list of categories"""

        print("Pull categories from API")
        categories = self.spotipy.categories()['categories']['items']

        for c in tqdm(categories, desc='Inserting categories'):

            self.connector.insert_category(c)
            self.ingest_category_playlist(c['id'])

    def ingest_category_playlist(self, category_id):
        # This is a list of playlists

        try:
            play_lists = self.spotipy.category_playlists(
                category_id)['playlists']['items']
        except SpotifyException as e:
            print('Category %s play list ingestion failed' % category_id)
        else:
            for p in tqdm(play_lists, desc='Insertiing Category playlists'):

                self.connector.insert_playlist(p)
                # TODO: insert playlist category relation
                # category id and p['id']

                # TODO: ingest tracks
                # p['tracks']

    def clear_database(self):
        """Clears the database this ingerstor is connected to."""

        # TODO: add warning

        self.connector.clear_database()
Ejemplo n.º 15
0
class SpotifyConnection(object):
    def __init__(self, user_data):
        self.user_name = user_data['user_name']
        token = spotipy.util.prompt_for_user_token(
            self.user_name,
            scope='user-read-recently-played',
            client_id=user_data['client_id'],
            client_secret=user_data['client_secret'],
            redirect_uri=user_data['redirect_uri'])
        self.client = Spotify(auth=token)
        self.db = self.init_db()

    def init_db(self):
        return PostgreSQLConnection()

    def get_artist(self, artist_id):
        artist = self.db.session.query(Artist).get(artist_id)
        if artist:
            return artist
        else:
            artist_response = self.client.artist(artist_id)
            artist = Artist()
            artist.artist_id = artist_id
            artist.artist_data = artist_response
            self.db.save_instance(artist)
            print("> Artist {} was not in database.".format(
                artist.artist_data['name']))
            return self.db.session.query(Artist).get(artist_id)

    def get_album(self, album_id):
        album = self.db.session.query(Album).get(album_id)
        if album:
            return album
        else:
            album_response = self.client.album(album_id)
            album = Album()
            album.album_data = album_response
            album.album_id = album_response['id']
            # Artists
            for album_artist_response in album_response['artists']:
                album.artists.append(
                    self.get_artist(album_artist_response['id']))
            self.db.save_instance(album)
            print("> Album {} was not in database.".format(
                album.album_data['name']))
            return self.db.session.query(Album).get(album_id)

    def get_track(self, track_id):
        track = self.db.session.query(Track).get(track_id)
        if track:
            return track
        else:
            response = self.client.track(track_id)

            track = Track()
            track.track_id = track_id
            track.track_data = response
            # Album
            track.album = self.get_album(response['album']['id'])
            # Artists
            for artist_response in response['artists']:
                track.artists.append(self.get_artist(artist_response['id']))
            # Audio feature
            audio_feature_response = self.client.audio_features(track_id)[0]
            if audio_feature_response:  # Some tracks do not have audio features
                track.audio_feature_data = audio_feature_response
            print("> Track {} was not in database.".format(
                track.track_data['name']))
            self.db.save_instance(track)
            return self.db.session.query(Track).get(track_id)

    def get_play_from_played_at_utc_and_track_id(self, played_at_utc,
                                                 track_id):
        played_at_utc = convert_played_at_from_response_to_datetime(
            played_at_utc)
        played_at_utc = set_timezone_to_datetime(played_at_utc, timezone='UTC')
        played_at_cet = convert_datetime_from_timezone_to_timezone(
            played_at_utc, from_tz_code='UTC', to_tz_code='CET')
        # Play
        play = Play()
        play.user_name = self.user_name
        play.played_at_utc_timestamp = played_at_utc.timestamp() * 1000
        play.played_at_utc = played_at_utc
        play.played_at_cet = played_at_cet
        play.day = played_at_cet.day
        play.month = played_at_cet.month
        play.year = played_at_cet.year
        play.hour = played_at_cet.hour
        play.minute = played_at_cet.minute
        play.second = played_at_cet.second
        play.day_of_week = played_at_cet.weekday()
        play.week_of_year = played_at_cet.date().isocalendar()[1]
        # Track
        track = self.get_track(track_id)
        play.track = track
        play.track_id = track_id
        return play

    def _get_play_tuples_from_response(self, response):
        plays = []
        for item in response['items']:
            play_tuple = (item['played_at'], item['track']['id'])
            plays.append(play_tuple)
        return plays

    def _get_play_tuples(self, limit=50, after=None):
        play_tuples = []
        response = self.client._get('me/player/recently-played',
                                    after=after,
                                    limit=limit)
        play_tuples.extend(self._get_play_tuples_from_response(response))

        while response and 'next' in response:
            response = self.client.next(response)
            if response:
                play_tuples.extend(
                    self._get_play_tuples_from_response(response))

        return play_tuples

    def extract_plays(self):
        print("* Extracting latest plays of {}.".format(self.user_name))
        play_tuples = self._get_play_tuples()

        for played_at, track_id in play_tuples:
            play = self.get_play_from_played_at_utc_and_track_id(
                played_at, track_id)
            self.db.save_play(play)