Skip to content

Instantly share code, notes, and snippets.

@succinct
Created March 21, 2022 03:51
Show Gist options
  • Save succinct/2d7157f4eb7ed7333166a80213171581 to your computer and use it in GitHub Desktop.
Save succinct/2d7157f4eb7ed7333166a80213171581 to your computer and use it in GitHub Desktop.
Retrieve cover art from Spotify API by searching for artist and track title
# Spotipy: https://spotipy.readthedocs.io/
import argparse, os, re, requests, shutil, spotipy, sys
from spotipy.oauth2 import SpotifyClientCredentials
def main():
parser=argparse.ArgumentParser()
parser.add_argument('--id', help='[REQUIRED] Your Spotify API app client ID (see https://developer.spotify.com/dashboard)')
parser.add_argument('--secret', help='[REQUIRED] Your Spotify API app client secret')
parser.add_argument('--track', help='The full label for the track, in the format "<artist> - <title>"')
parser.add_argument('--artist', help='The track artist (overrides the --track argument)')
parser.add_argument('--title', help='The title of the track (overrides the --track argument)')
parser.add_argument('--output', help='The path in which to output the cover image (defaults to the working directory, image name "cover.png")')
parser.add_argument('--size', help='The size of the cover art to retrieve: large|medium|small (default: "large")')
args=parser.parse_args()
client_id = args.id
client_secret = args.secret
artist = args.artist or False
title = args.title or False
output = args.output or os.path.dirname(os.path.realpath(sys.argv[0])) + '\\cover.png'
size = args.size or 'large'
if not client_id or not client_secret:
print("You must specify your Spotify API client ID with --id and your client secret with --secret (see https://developer.spotify.com/dashboard)")
sys.exit()
# Get artist/title from track info, or explicitly
if not artist and not title:
trackinfo = args.track or False
if trackinfo:
# do things
[artist, title] = trackinfo.split(" - ", 1)
else:
print("You must specify either --track, or --artist & --title")
sys.exit()
try:
auth_manager = SpotifyClientCredentials(client_id=client_id, client_secret=client_secret)
spotify = spotipy.Spotify(auth_manager=auth_manager)
q = f"artist:{artist} track:{title}"
if not re.search('live', title, re.IGNORECASE):
q = f"{q} NOT live" # ignore live releases
print(f"[Spotify] Searching for '{q}'...")
results = spotify.search(q=q, limit=1, type='track')
cover_url = False
for i, track in enumerate(results['tracks']['items']): # There will be at most one result per the query options
contributing_artists = False
for i, contributing_artist in enumerate(track['artists']):
if contributing_artists:
contributing_artists = f"{contributing_artists}, {contributing_artist['name']}"
else:
contributing_artists = contributing_artist['name']
print(f"[Spotify] Match found: {contributing_artists} {track['name']}")
image_sizes = track['album']['images']
match size:
case 'large':
cover_image = image_sizes[0]
case 'medium':
cover_image = image_sizes[1]
case 'small':
cover_image = image_sizes[2]
cover_url = cover_image['url']
if cover_url:
# Download image
req = requests.get(cover_url, stream = True)
if req.status_code == 200:
# Set decode_content value to True, otherwise the downloaded image file's size will be zero.
req.raw.decode_content = True
with open(output, 'wb') as file_output:
shutil.copyfileobj(req.raw, file_output)
print(f"Cover image saved to {output} ({size})")
else:
print('Image could not be retrieved!')
else:
print(f"Unable to find cover art for '{artist} - {title}'")
except: # catch *all* exceptions
e = sys.exc_info()[0]
print(f"Error: {e}")
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment