A light weight Python library for the Spotify Web API
Spotify's discovery and browse features including featured playlists, new releases, categories, personalized recommendations, and audio analysis capabilities. These endpoints provide access to Spotify's curated content and recommendation engine.
Access Spotify's editorially curated featured playlists and new releases.
def featured_playlists(self, country=None, locale=None, timestamp=None, limit=20, offset=0):
"""
Get featured playlists.
Args:
country (str, optional): ISO 3166-1 alpha-2 country code
locale (str, optional): Desired language for results (ISO 639-1 language code and ISO 3166-1 alpha-2 country code)
timestamp (str, optional): ISO 8601 timestamp for when to retrieve featured playlists
limit (int): Number of playlists to return (1-50, default: 20)
offset (int): Index of first playlist (default: 0)
Returns:
dict: Object with message and paging object of featured playlists
"""
def new_releases(self, country=None, limit=20, offset=0):
"""
Get new album releases.
Args:
country (str, optional): ISO 3166-1 alpha-2 country code
limit (int): Number of albums to return (1-50, default: 20)
offset (int): Index of first album (default: 0)
Returns:
dict: Paging object of new album releases
"""Browse Spotify's genre and mood categories with associated playlists.
def categories(self, country=None, locale=None, limit=20, offset=0):
"""
Get list of categories.
Args:
country (str, optional): ISO 3166-1 alpha-2 country code
locale (str, optional): Desired language for results
limit (int): Number of categories to return (1-50, default: 20)
offset (int): Index of first category (default: 0)
Returns:
dict: Paging object of category objects
"""
def category(self, category_id, country=None, locale=None):
"""
Get single category.
Args:
category_id (str): Spotify category ID
country (str, optional): ISO 3166-1 alpha-2 country code
locale (str, optional): Desired language for results
Returns:
dict: Category object with id, name, href, icons
"""
def category_playlists(self, category_id, country=None, limit=20, offset=0):
"""
Get playlists for a category.
Args:
category_id (str): Spotify category ID
country (str, optional): ISO 3166-1 alpha-2 country code
limit (int): Number of playlists to return (1-50, default: 20)
offset (int): Index of first playlist (default: 0)
Returns:
dict: Paging object of playlists for the category
"""Get personalized track recommendations based on seed tracks, artists, and genres with fine-tuned audio features.
def recommendations(self, seed_artists=None, seed_genres=None, seed_tracks=None,
limit=20, country=None, **kwargs):
"""
Get track recommendations.
Args:
seed_artists (list, optional): List of artist IDs for seed (max 5 total seeds)
seed_genres (list, optional): List of genre names for seed (max 5 total seeds)
seed_tracks (list, optional): List of track IDs for seed (max 5 total seeds)
limit (int): Number of recommendations to return (1-100, default: 20)
country (str, optional): ISO 3166-1 alpha-2 country code
**kwargs: Audio feature targets and ranges (min_*, max_*, target_*)
Audio Feature Parameters:
- acousticness: 0.0-1.0
- danceability: 0.0-1.0
- duration_ms: milliseconds
- energy: 0.0-1.0
- instrumentalness: 0.0-1.0
- key: 0-11 (C, C#, D, etc.)
- liveness: 0.0-1.0
- loudness: -60.0 to 0.0 dB
- mode: 0 (minor) or 1 (major)
- popularity: 0-100
- speechiness: 0.0-1.0
- tempo: BPM
- time_signature: 3-7
- valence: 0.0-1.0 (positivity)
Returns:
dict: Recommendations object with tracks array and seed info
"""
def recommendation_genre_seeds(self):
"""
Get available genre seeds for recommendations.
Returns:
dict: Object containing list of available genre strings
"""Detailed audio analysis and features for tracks.
def audio_features(self, tracks=[]):
"""
Get audio features for tracks.
Args:
tracks (list): List of track IDs or URIs (max 100)
Returns:
dict: Audio features objects with acousticness, danceability, energy, etc.
"""
def audio_analysis(self, track_id):
"""
Get detailed audio analysis for a track.
Args:
track_id (str): Spotify track ID or URI
Returns:
dict: Detailed audio analysis with bars, beats, sections, segments, tatums, meta, track
"""import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
sp = spotipy.Spotify(client_credentials_manager=SpotifyClientCredentials())
# Get featured playlists for US market
featured = sp.featured_playlists(country='US', limit=10)
print(f"Featured message: {featured['message']}")
print("\\nFeatured playlists:")
for playlist in featured['playlists']['items']:
print(f" 📋 {playlist['name']} by {playlist['owner']['display_name']}")
print(f" {playlist['tracks']['total']} tracks, {playlist['followers']['total']} followers")
print(f" {playlist['description']}")
# Get new releases
new_releases = sp.new_releases(country='US', limit=10)
print("\\n🆕 New album releases:")
for album in new_releases['albums']['items']:
artist_names = ', '.join([artist['name'] for artist in album['artists']])
print(f" 💿 {album['name']} - {artist_names}")
print(f" Released: {album['release_date']} | Type: {album['album_type']}")
if album['total_tracks'] > 1:
print(f" {album['total_tracks']} tracks")# Get all categories
categories = sp.categories(country='US', limit=50)
print("🎭 Available categories:")
category_list = categories['categories']['items']
for category in category_list[:10]: # Show first 10
print(f" {category['name']} (ID: {category['id']})")
# Explore specific category
pop_category = sp.category('pop', country='US')
print(f"\\n📂 Category: {pop_category['name']}")
# Get playlists for pop category
pop_playlists = sp.category_playlists('pop', country='US', limit=20)
print(f"\\nTop pop playlists:")
for playlist in pop_playlists['playlists']['items']:
print(f" 🎵 {playlist['name']}")
print(f" {playlist['tracks']['total']} tracks, {playlist['followers']['total']} followers")# Get available genres
genres = sp.recommendation_genre_seeds()
print(f"Available genres: {', '.join(genres['genres'][:10])}...") # Show first 10
# Get recommendations based on favorite artists and genres
recommendations = sp.recommendations(
seed_artists=['4Z8W4fKeB5YxbusRsdQVPb'], # Radiohead
seed_genres=['alternative', 'indie'],
seed_tracks=['4iV5W9uYEdYUVa79Axb7Rh'], # Mr. Brightside
limit=20,
country='US'
)
print("\\n🎯 Personalized recommendations:")
for track in recommendations['tracks']:
artist_names = ', '.join([artist['name'] for artist in track['artists']])
print(f" 🎵 {track['name']} - {artist_names}")
print(f" Popularity: {track['popularity']}/100")
# Show seed information
print("\\n🌱 Based on seeds:")
for seed in recommendations['seeds']:
print(f" {seed['type']}: {seed.get('id', 'N/A')} (after filtering: {seed['afterFilteringSize']})")# Get upbeat, danceable recommendations
upbeat_recs = sp.recommendations(
seed_genres=['pop', 'dance'],
limit=15,
target_danceability=0.8, # High danceability
target_energy=0.7, # High energy
target_valence=0.8, # Positive mood
min_tempo=120, # At least 120 BPM
max_tempo=140, # Max 140 BPM
target_popularity=70 # Reasonably popular
)
print("🕺 Upbeat, danceable recommendations:")
for track in upbeat_recs['tracks']:
artist_names = ', '.join([artist['name'] for artist in track['artists']])
print(f" 💃 {track['name']} - {artist_names}")
# Get chill, acoustic recommendations
chill_recs = sp.recommendations(
seed_genres=['acoustic', 'chill'],
limit=10,
target_acousticness=0.8, # Highly acoustic
target_energy=0.3, # Low energy
target_valence=0.6, # Moderately positive
max_loudness=-10, # Not too loud
target_instrumentalness=0.1 # Some vocals
)
print("\\n😌 Chill, acoustic recommendations:")
for track in chill_recs['tracks']:
artist_names = ', '.join([artist['name'] for artist in track['artists']])
print(f" 🎸 {track['name']} - {artist_names}")# Analyze audio features of popular tracks
track_ids = [
'4iV5W9uYEdYUVa79Axb7Rh', # Mr. Brightside
'0VjIjW4GlUAOLklx2J', # Bohemian Rhapsody
'1301WleyT98MSxVHPZCA6M' # Sweet Child O' Mine
]
# Get basic track info
tracks_info = sp.tracks(track_ids)
features = sp.audio_features(track_ids)
print("🎵 Audio Features Analysis:")
for track_info, feature in zip(tracks_info['tracks'], features):
if feature: # Check if features available
print(f"\\n🎧 {track_info['name']} - {track_info['artists'][0]['name']}")
print(f" Key: {feature['key']} | Mode: {'Major' if feature['mode'] else 'Minor'}")
print(f" Tempo: {feature['tempo']:.1f} BPM | Time Signature: {feature['time_signature']}/4")
print(f" Energy: {feature['energy']:.2f} | Danceability: {feature['danceability']:.2f}")
print(f" Valence: {feature['valence']:.2f} | Acousticness: {feature['acousticness']:.2f}")
print(f" Loudness: {feature['loudness']:.1f} dB | Duration: {feature['duration_ms']/1000:.1f}s")# Get detailed analysis for a track
track_id = '4iV5W9uYEdYUVa79Axb7Rh' # Mr. Brightside
analysis = sp.audio_analysis(track_id)
print("🔬 Detailed Audio Analysis:")
print(f"Duration: {analysis['track']['duration']:.1f}s")
print(f"Key: {analysis['track']['key']} | Mode: {analysis['track']['mode']}")
print(f"Time Signature: {analysis['track']['time_signature']}")
print(f"Tempo: {analysis['track']['tempo']:.1f} BPM")
# Analyze sections
print(f"\\n📊 Song Structure:")
print(f"Bars: {len(analysis['bars'])}")
print(f"Beats: {len(analysis['beats'])}")
print(f"Sections: {len(analysis['sections'])}")
print(f"Segments: {len(analysis['segments'])}")
# Show first few sections
print("\\n🎼 Sections breakdown:")
for i, section in enumerate(analysis['sections'][:5]):
start_time = section['start']
duration = section['duration']
confidence = section['confidence']
loudness = section['loudness']
tempo = section['tempo']
key = section['key']
print(f" Section {i+1}: {start_time:.1f}s-{start_time+duration:.1f}s")
print(f" Tempo: {tempo:.1f} BPM | Key: {key} | Loudness: {loudness:.1f} dB")
print(f" Confidence: {confidence:.2f}")def discover_music_by_mood(mood="happy", limit=15):
"""Discover music based on mood using audio features."""
mood_profiles = {
"happy": {
"seed_genres": ["pop", "dance", "funk"],
"target_valence": 0.8,
"target_energy": 0.7,
"target_danceability": 0.7,
"min_tempo": 110
},
"sad": {
"seed_genres": ["indie", "alternative", "singer-songwriter"],
"target_valence": 0.3,
"target_energy": 0.4,
"target_acousticness": 0.6,
"max_tempo": 100
},
"chill": {
"seed_genres": ["chill", "ambient", "lo-fi"],
"target_energy": 0.3,
"target_acousticness": 0.7,
"target_instrumentalness": 0.5,
"max_loudness": -15
},
"workout": {
"seed_genres": ["electro", "hip-hop", "rock"],
"target_energy": 0.9,
"target_danceability": 0.8,
"min_tempo": 130,
"max_tempo": 160
}
}
if mood not in mood_profiles:
print(f"Mood '{mood}' not available. Try: {', '.join(mood_profiles.keys())}")
return
profile = mood_profiles[mood]
recommendations = sp.recommendations(limit=limit, **profile)
print(f"🎭 {mood.title()} Music Recommendations:")
for track in recommendations['tracks']:
artist_names = ', '.join([artist['name'] for artist in track['artists']])
print(f" 🎵 {track['name']} - {artist_names}")
print(f" Album: {track['album']['name']} | Popularity: {track['popularity']}/100")
# Discover music for different moods
discover_music_by_mood("happy", 10)
print()
discover_music_by_mood("chill", 8)def explore_market(country_code, limit=5):
"""Explore what's popular in a specific market."""
print(f"🌍 Exploring {country_code} market:")
# Featured playlists
try:
featured = sp.featured_playlists(country=country_code, limit=limit)
print(f"\\n📋 Featured Playlists:")
for playlist in featured['playlists']['items']:
print(f" {playlist['name']} ({playlist['tracks']['total']} tracks)")
except Exception as e:
print(f" Featured playlists not available: {e}")
# New releases
try:
releases = sp.new_releases(country=country_code, limit=limit)
print(f"\\n💿 New Releases:")
for album in releases['albums']['items']:
artist_names = ', '.join([artist['name'] for artist in album['artists']])
print(f" {album['name']} - {artist_names}")
except Exception as e:
print(f" New releases not available: {e}")
# Categories
try:
categories = sp.categories(country=country_code, limit=limit)
print(f"\\n🎭 Popular Categories:")
for category in categories['categories']['items']:
print(f" {category['name']}")
except Exception as e:
print(f" Categories not available: {e}")
# Explore different markets
markets = ['US', 'GB', 'DE', 'JP', 'BR']
for market in markets:
explore_market(market, 3)
print("-" * 50)When using recommendations with audio feature parameters:
Use min_*, max_*, and target_* prefixes with these feature names for recommendation fine-tuning.
Install with Tessl CLI
npx tessl i tessl/pypi-spotipy