DEV Community

Alex Spinov
Alex Spinov

Posted on

Spotify API: Build a Music Discovery Tool in 50 Lines of Python

Spotify's API is one of the most generous free APIs available. You get access to 100 million tracks, audio features, recommendations, and playlist data — all for free.

Here's how to build a music discovery tool in 50 lines.

Setup (2 Minutes)

  1. Go to developer.spotify.com
  2. Create an app (free)
  3. Copy your Client ID and Client Secret
pip install httpx
Enter fullscreen mode Exit fullscreen mode

Authentication

Spotify uses Client Credentials flow for public data:

import httpx
import base64

CLIENT_ID = 'your_client_id'
CLIENT_SECRET = 'your_client_secret'

def get_token():
    auth = base64.b64encode(f'{CLIENT_ID}:{CLIENT_SECRET}'.encode()).decode()
    r = httpx.post('https://accounts.spotify.com/api/token',
        headers={'Authorization': f'Basic {auth}'},
        data={'grant_type': 'client_credentials'}
    )
    return r.json()['access_token']

token = get_token()
headers = {'Authorization': f'Bearer {token}'}
Enter fullscreen mode Exit fullscreen mode

Search for Artists

def search_artist(name):
    r = httpx.get('https://api.spotify.com/v1/search',
        headers=headers,
        params={'q': name, 'type': 'artist', 'limit': 1}
    )
    artist = r.json()['artists']['items'][0]
    return {
        'name': artist['name'],
        'id': artist['id'],
        'followers': artist['followers']['total'],
        'genres': artist['genres'],
        'popularity': artist['popularity']
    }

print(search_artist('Radiohead'))
# {'name': 'Radiohead', 'followers': 11M, 'genres': ['art rock', ...], 'popularity': 79}
Enter fullscreen mode Exit fullscreen mode

Get Top Tracks

def top_tracks(artist_id, market='US'):
    r = httpx.get(f'https://api.spotify.com/v1/artists/{artist_id}/top-tracks',
        headers=headers,
        params={'market': market}
    )
    return [{
        'name': t['name'],
        'album': t['album']['name'],
        'popularity': t['popularity'],
        'preview_url': t['preview_url']
    } for t in r.json()['tracks'][:5]]
Enter fullscreen mode Exit fullscreen mode

Get Audio Features (The Cool Part)

Spotify analyzes every track and provides:

  • danceability — how suitable for dancing (0-1)
  • energy — intensity and activity (0-1)
  • valence — musical positivity (0-1)
  • tempo — BPM
  • acousticness — acoustic vs electronic (0-1)
def audio_features(track_id):
    r = httpx.get(f'https://api.spotify.com/v1/audio-features/{track_id}',
        headers=headers
    )
    f = r.json()
    return {
        'danceability': f['danceability'],
        'energy': f['energy'],
        'valence': f['valence'],
        'tempo': f['tempo'],
        'acousticness': f['acousticness']
    }
Enter fullscreen mode Exit fullscreen mode

Discover Similar Artists

def discover(artist_name):
    """Find similar artists with different vibes."""
    artist = search_artist(artist_name)
    r = httpx.get(f'https://api.spotify.com/v1/artists/{artist["id"]}/related-artists',
        headers=headers
    )
    related = r.json()['artists'][:10]
    return [{
        'name': a['name'],
        'genres': a['genres'][:3],
        'popularity': a['popularity'],
        'followers': f"{a['followers']['total']:,}"
    } for a in related]

# Find artists similar to Radiohead
for artist in discover('Radiohead'):
    print(f"{artist['name']} ({artist['popularity']}/100) — {', '.join(artist['genres'])}")
Enter fullscreen mode Exit fullscreen mode

Get Recommendations

def get_recommendations(seed_artists=None, seed_genres=None, **kwargs):
    params = {'limit': 10}
    if seed_artists:
        params['seed_artists'] = ','.join(seed_artists)
    if seed_genres:
        params['seed_genres'] = ','.join(seed_genres)
    params.update(kwargs)  # target_energy=0.8, min_tempo=120, etc.

    r = httpx.get('https://api.spotify.com/v1/recommendations',
        headers=headers, params=params
    )
    return [{'name': t['name'], 'artist': t['artists'][0]['name']} 
            for t in r.json()['tracks']]

# High energy dance tracks
recs = get_recommendations(
    seed_genres=['electronic', 'dance'],
    target_energy=0.9,
    target_danceability=0.8,
    min_tempo=120
)
Enter fullscreen mode Exit fullscreen mode

Rate Limits

  • Free tier: ~180 requests/minute
  • No API key cost
  • Rate limit headers in response

What You Can Build

  • Mood-based playlist generator
  • Artist similarity explorer
  • Music taste analyzer
  • Genre evolution tracker
  • DJ set builder (match BPM/key)

More API Tutorials


What would you build with the Spotify API? Mood playlists? Music analytics? Something else? 👇

API tutorials at dev.to/0012303

Top comments (0)