Skip to content

Commit

Permalink
Codebase Refactor for v3
Browse files Browse the repository at this point in the history
Implemented suggestions for spotipy-dev#652
Major changes include:-
- Using if expressions than if conditions
list comprehensions instead of a for loop for smaller logical blocks.
- Usage of f-strings ( I saw that the env supports 3.4 but f-strings have been added from Python 3.6). So should I refactor this?
- Simplifying if/else code blocks to be more concise.
- Merge nested conditional clauses.
  • Loading branch information
HighnessAtharva committed Apr 8, 2023
1 parent f005732 commit cc5260c
Show file tree
Hide file tree
Showing 24 changed files with 190 additions and 282 deletions.
19 changes: 13 additions & 6 deletions TUTORIAL.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
# Spotipy Tutorial for Beginners

Hello and welcome to the Spotipy Tutorial for Beginners. If you have limited experience coding in Python and have never used Spotipy or the Spotify API before, you've come to the right place. This tutorial will walk you through all the steps necessary to set up Spotipy and use it to accomplish a simple task.

## Prerequisites

In order to complete this tutorial successfully, there are a few things that you should already have installed:

**1. pip package manager**
**1. pip package manager**

You can check to see if you have pip installed by opening up Terminal and typing the following command: pip --version
If you see a version number, pip is installed and you're ready to proceed. If not, instructions for downloading the latest version of pip can be found here: https://pip.pypa.io/en/stable/cli/pip_download/

If you see a version number, pip is installed and you're ready to proceed. If not, instructions for downloading the latest version of pip can be found here: <https://pip.pypa.io/en/stable/cli/pip_download/>

**2. python3**

Spotipy is written in Python, so you'll need to have the lastest version of Python installed in order to use Spotipy. Check if you already have Python installed with the Terminal command: python --version
If you see a version number, Python is already installed. If not, you can download it here: https://www.python.org/downloads/
If you see a version number, Python is already installed. If not, you can download it here: <https://www.python.org/downloads/>

**3. experience with basic Linux commands**
**3. xperience with basic Linux commands**

This tutorial will be easiest if you have some knowledge of how to use Linux commands to create and navigate folders and files on your computer. If you're not sure how to create, edit and delete files and directories from Terminal, learn about basic Linux commands [here](https://ubuntu.com/tutorials/command-line-for-beginners#1-overview) before continuing.

Once those three setup items are taken care of, you're ready to start learning how to use Spotipy!

## Step 1. Creating a Spotify Account

Spotipy relies on the Spotify API. In order to use the Spotify API, you'll need to create a Spotify developer account.

A. Visit the [Spotify developer portal](https://developer.spotify.com/dashboard/). If you already have a Spotify account, click "Log in" and enter your username and password. Otherwise, click "Sign up" and follow the steps to create an account. After you've signed in or signed up, you should be redirected to your developer dashboard.
Expand All @@ -39,6 +41,7 @@ A. Create a folder somewhere on your computer where you'd like to store the code
B. In that folder, create a Python file named main.py. You can create the file directly from Terminal using a built in text editor like Vim, which comes preinstalled on Linux operating systems. To create the file with Vim, ensure that you are in your new directory, then run: vim main.py

C. Paste the following code into your main.py file:

```
import spotipy
from spotipy.oauth2 import SpotifyOAuth
Expand All @@ -48,6 +51,7 @@ sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id="YOUR_APP_CLIENT_ID",
redirect_uri="YOUR_APP_REDIRECT_URI",
scope="user-library-read"))
```

D. Replace YOUR_APP_CLIENT_ID and YOUR_APP_CLIENT_SECRET with the values you copied and saved in step 1D. Replace YOUR_APP_REDIRECT_URI with the URI you set in step 1C.

## Step 3. Start Using Spotipy
Expand All @@ -59,10 +63,13 @@ For now, let's assume that we want to print the names of all of the albums on Sp
A. First, we need to find Taylor Swift's Spotify URI (Uniform Resource Indicator). Every entity (artist, album, song, etc.) has a URI that can identify it. To find Taylor's URI, navigate to [her page on Spotify](https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02) and look at the URI in your browser. Everything there that follows the last backslash in the URL path is Taylor's URI, in this case: 06HL4z0CvFAxyc27GXpf02

B. Add the URI as a variable in main.py. Notice the prefix added the the URI:

```
taylor_uri = 'spotify:artist:06HL4z0CvFAxyc27GXpf02'
```

C. Add the following code that will get all of Taylor's album names from Spotify and iterate through them to print them all to standard output.

```
results = sp.artist_albums(taylor_uri, album_type='album')
albums = results['items']
Expand All @@ -78,4 +85,4 @@ D. Close main.py and return to the directory that contains main.py. You can then

E. You may see a window open in your browser asking you to authorize the application. Do so - you will only have to do this once.

F. Return to your terminal - you should see all of Taylor's albums printed out there.
F. Return to your terminal - you should see all of Taylor's albums printed out there.
4 changes: 1 addition & 3 deletions examples/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,7 @@ def currently_playing():
return redirect('/')
spotify = spotipy.Spotify(auth_manager=auth_manager)
track = spotify.current_user_playing_track()
if not track is None:
return track
return "No track currently playing."
return track if track is not None else "No track currently playing."


@app.route('/current_user')
Expand Down
7 changes: 2 additions & 5 deletions examples/artist_albums.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,9 @@ def get_args():


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


def show_artist_albums(artist):
Expand Down
7 changes: 2 additions & 5 deletions examples/artist_discography.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,9 @@ def get_args():


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


def show_album_tracks(album):
Expand Down
7 changes: 2 additions & 5 deletions examples/artist_recommendations.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,9 @@ def get_args():


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


def show_recommendations_for_artist(artist):
Expand Down
2 changes: 1 addition & 1 deletion examples/contains_a_saved_track.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
if len(sys.argv) > 1:
tid = sys.argv[1]
else:
print("Usage: %s track-id ..." % (sys.argv[0],))
print(f"Usage: {sys.argv[0]} track-id ...")
sys.exit()

sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))
Expand Down
2 changes: 1 addition & 1 deletion examples/delete_a_saved_track.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
if len(sys.argv) > 1:
tid = sys.argv[1]
else:
print("Usage: %s track-id ..." % (sys.argv[0],))
print(f"Usage: {sys.argv[0]} track-id ...")
sys.exit()

sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))
Expand Down
2 changes: 1 addition & 1 deletion examples/playlist_all_non_local_tracks.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@


# print result
print("Playlist length: " + str(len(tracks)) + "\nExcluding: " + str(i))
print(f"Playlist length: {len(tracks)}" + "\nExcluding: " + str(i))
4 changes: 1 addition & 3 deletions examples/remove_specific_tracks_from_playlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
tid, pos = t_pos.split(',')
track_ids.append({"uri": tid, "positions": [int(pos)]})
else:
print(
"Usage: %s playlist_id track_id,pos track_id,pos ..." %
(sys.argv[0],))
print(f"Usage: {sys.argv[0]} playlist_id track_id,pos track_id,pos ...")
sys.exit()

scope = 'playlist-modify-public'
Expand Down
2 changes: 1 addition & 1 deletion examples/remove_tracks_from_playlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
playlist_id = sys.argv[2]
track_ids = sys.argv[3:]
else:
print("Usage: %s playlist_id track_id ..." % (sys.argv[0]))
print(f"Usage: {sys.argv[0]} playlist_id track_id ...")
sys.exit()

scope = 'playlist-modify-public'
Expand Down
2 changes: 1 addition & 1 deletion examples/replace_tracks_in_playlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
playlist_id = sys.argv[1]
track_ids = sys.argv[2:]
else:
print("Usage: %s playlist_id track_id ..." % (sys.argv[0],))
print(f"Usage: {sys.argv[0]} playlist_id track_id ...")
sys.exit()

scope = 'playlist-modify-public'
Expand Down
6 changes: 1 addition & 5 deletions examples/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@
import sys
import pprint

if len(sys.argv) > 1:
search_str = sys.argv[1]
else:
search_str = 'Radiohead'

search_str = sys.argv[1] if len(sys.argv) > 1 else 'Radiohead'
sp = spotipy.Spotify(auth_manager=SpotifyClientCredentials())
result = sp.search(search_str)
pprint.pprint(result)
5 changes: 1 addition & 4 deletions examples/show_featured_playlists.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,4 @@
for i, item in enumerate(playlists['items']):
print(playlists['offset'] + i, item['name'])

if playlists['next']:
response = sp.next(playlists)
else:
response = None
response = sp.next(playlists) if playlists['next'] else None
5 changes: 1 addition & 4 deletions examples/show_new_releases.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,4 @@
for i, item in enumerate(albums['items']):
print(albums['offset'] + i, item['name'])

if albums['next']:
response = sp.next(albums)
else:
response = None
response = sp.next(albums) if albums['next'] else None
8 changes: 2 additions & 6 deletions examples/show_related.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,10 @@
import spotipy
import sys

if len(sys.argv) > 1:
artist_name = sys.argv[1]
else:
artist_name = 'weezer'

artist_name = sys.argv[1] if len(sys.argv) > 1 else 'weezer'
auth_manager = SpotifyClientCredentials()
sp = spotipy.Spotify(auth_manager=auth_manager)
result = sp.search(q='artist:' + artist_name, type='artist')
result = sp.search(q=f'artist:{artist_name}', type='artist')
try:
name = result['artists']['items'][0]['name']
uri = result['artists']['items'][0]['uri']
Expand Down
6 changes: 2 additions & 4 deletions examples/show_tracks.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@
given a list of track IDs show the artist and track name
'''

from spotipy.oauth2 import SpotifyClientCredentials
import sys
import spotipy

if __name__ == '__main__':
max_tracks_per_call = 50
if len(sys.argv) > 1:
file = open(sys.argv[1])
else:
file = sys.stdin
file = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin
tids = file.read().split()

auth_manager = SpotifyClientCredentials()
Expand Down
6 changes: 1 addition & 5 deletions examples/show_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@
import sys
import pprint

if len(sys.argv) > 1:
username = sys.argv[1]
else:
username = 'plamere'

username = sys.argv[1] if len(sys.argv) > 1 else 'plamere'
auth_manager = SpotifyClientCredentials()
sp = spotipy.Spotify(auth_manager=auth_manager)
sp.trace = True
Expand Down
8 changes: 2 additions & 6 deletions examples/simple3.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,8 @@

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

if len(sys.argv) > 1:
name = ' '.join(sys.argv[1:])
else:
name = 'Radiohead'

results = sp.search(q='artist:' + name, type='artist')
name = ' '.join(sys.argv[1:]) if len(sys.argv) > 1 else 'Radiohead'
results = sp.search(q=f'artist:{name}', type='artist')
items = results['artists']['items']
if len(items) > 0:
artist = items[0]
Expand Down
2 changes: 1 addition & 1 deletion examples/title_chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
sp = spotipy.Spotify(auth_manager=auth_manager)


skiplist = set(['dm', 'remix'])
skiplist = {'dm', 'remix'}
max_offset = 500
seen = set()

Expand Down
11 changes: 2 additions & 9 deletions examples/user_public_playlists.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@
auth_manager = SpotifyClientCredentials()
sp = spotipy.Spotify(auth_manager=auth_manager)

user = 'spotify'

if len(sys.argv) > 1:
user = sys.argv[1]

user = sys.argv[1] if len(sys.argv) > 1 else 'spotify'
playlists = sp.user_playlists(user)

while playlists:
Expand All @@ -25,7 +21,4 @@
playlists['offset'],
playlist['uri'],
playlist['name']))
if playlists['next']:
playlists = sp.next(playlists)
else:
playlists = None
playlists = sp.next(playlists) if playlists['next'] else None
33 changes: 15 additions & 18 deletions spotipy/cache_handler.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import pathlib
__all__ = [
'CacheHandler',
'CacheFileHandler',
Expand Down Expand Up @@ -57,22 +58,19 @@ def __init__(self,
(will set `cache_path` to `.cache-{username}`)
"""

if cache_path:
self.cache_path = cache_path
else:
if not cache_path:
cache_path = ".cache"
username = (username or os.getenv(CLIENT_CREDS_ENV_VARS["client_username"]))
if username:
cache_path += "-" + str(username)
self.cache_path = cache_path
if username := (
username or os.getenv(CLIENT_CREDS_ENV_VARS["client_username"])
):
cache_path += f"-{str(username)}"
self.cache_path = cache_path

def get_cached_token(self):
token_info = None

try:
f = open(self.cache_path)
token_info_string = f.read()
f.close()
token_info_string = pathlib.Path(self.cache_path).read_text()
token_info = json.loads(token_info_string)

except IOError as error:
Expand All @@ -85,9 +83,8 @@ def get_cached_token(self):

def save_token_to_cache(self, token_info):
try:
f = open(self.cache_path, "w")
f.write(json.dumps(token_info))
f.close()
with open(self.cache_path, "w") as f:
f.write(json.dumps(token_info))
except IOError:
logger.warning('Couldn\'t write token to cache at: %s',
self.cache_path)
Expand Down Expand Up @@ -143,7 +140,7 @@ def save_token_to_cache(self, token_info):
try:
self.request.session['token_info'] = token_info
except Exception as e:
logger.warning("Error saving token to cache: " + str(e))
logger.warning(f"Error saving token to cache: {str(e)}")


class FlaskSessionCacheHandler(CacheHandler):
Expand All @@ -168,7 +165,7 @@ def save_token_to_cache(self, token_info):
try:
self.session["token_info"] = token_info
except Exception as e:
logger.warning("Error saving token to cache: " + str(e))
logger.warning(f"Error saving token to cache: {str(e)}")


class RedisCacheHandler(CacheHandler):
Expand All @@ -185,7 +182,7 @@ def __init__(self, redis, key=None):
(takes precedence over `token_info`)
"""
self.redis = redis
self.key = key if key else 'token_info'
self.key = key or 'token_info'

try:
from redis import RedisError # noqa: F401
Expand All @@ -205,7 +202,7 @@ def get_cached_token(self):
if token_info:
return json.loads(token_info)
except RedisError as e:
logger.warning('Error getting token from cache: ' + str(e))
logger.warning(f'Error getting token from cache: {str(e)}')

return token_info

Expand All @@ -215,4 +212,4 @@ def save_token_to_cache(self, token_info):
try:
self.redis.set(self.key, json.dumps(token_info))
except RedisError as e:
logger.warning('Error saving token to cache: ' + str(e))
logger.warning(f'Error saving token to cache: {str(e)}')

0 comments on commit cc5260c

Please sign in to comment.