关于 spotify-api
spotify-api 是用于调用 Spotify Web API 的技能,可搜索和管理音乐、播放列表及播放控制。它还可生成 SVG 封面图并转换为 PNG。
主要功能
- 01生成播放列表封面图
- 02按艺人、主题或歌曲创建播放列表
- 03搜索曲目、艺人、专辑和播放列表
- 04管理播放列表及其中曲目
- 05控制播放并访问用户数据
适用场景
- 01按艺人或氛围创建播放列表
- 02查找曲目并添加到播放列表
- 03生成并上传自定义播放列表封面
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ fabioc-aloha/ spotify-skill --skill spotify-api安装后在 Claude Code 中输入/spotify-api确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.env.exampleADVANCED_USAGE.mdCOVER_ART_TROUBLESHOOTING.mdrequirements.txtreferences/api_reference.mdauthentication_guide.mdCOVER_ART_LLM_GUIDE.mdscripts/cover_art_generator.pyexport_data.pyplaylist_creator.pyspotify_client.pytest_credentials.py详细介绍
Spotify API Skill
版本:0.9.1 | 发布日期:2025 年 10 月 22 日
概述
此技能直接与 Spotify Web API 交互,用于管理音乐和播放列表。
⚡ 独特功能:图像生成
🎨 此技能可以生成图像——这是 Claude 原生无法做到的!它会为 Spotify 播放列表创建自定义的 SVG 封面图,并采用适合缩略图查看的大号易读字体。每张封面图都会根据主题动态生成,包含适配的颜色、渐变和文字布局。
在以下情况下使用此技能:
- 🎨 生成封面图——创建自定义播放列表封面(绕过 Claude 内置的图像生成限制!)
- 🎵 根据艺人名称、主题或特定歌曲创建播放列表
- 🔍 搜索曲目、艺人和专辑
- ➕ 在播放列表中添加/移除曲目
- ▶️ 控制播放(播放、暂停、跳过)
- 📊 获取用户数据(个人资料、热门曲目、收听历史)
使用此技能的场景: 用户希望你创建播放列表、搜索音乐、管理其 Spotify 账户,或生成自定义封面图。
核心功能
- 🎨 封面图生成——通过 SVG → PNG 转换生成自定义图像(Claude 无法原生生成图像!)
- 智能创建播放列表——根据艺人、主题、歌词或歌曲列表创建播放列表
- 播放列表管理——创建、列出、更新和删除播放列表
- 搜索与发现——查找曲目、艺人、专辑和播放列表
- 曲目管理——添加/移除曲目、获取推荐
- 播放控制——播放、暂停、跳过、控制音量
- 用户资料库——访问已保存的曲目、个人资料和收听历史
快速入门
所有 Spotify API 操作都使用 scripts/spotify_client.py 中的 SpotifyClient 类。该客户端负责处理 OAuth 身份验证,并提供所有操作所需的方法。
前置条件
1. 启用网络访问(必需)
⚠️ 此技能需要网络访问权限才能连接 api.spotify.com
在 Claude Desktop 中,必须启用网络出口:
- 前往 Settings → Developer → Allow network egress
- 将其切换为 开启(蓝色)
- 在“Domain allowlist”下,选择以下任一选项:
- “All domains”(最简单),或
- “Specified domains” 并添加
api.spotify.com(更安全/受限)
- 这样此技能就可以向 Spotify 服务器发出 API 调用
如果未启用网络访问,API 调用将因连接错误而失败。
2. 安装依赖项
pip install -r requirements.txt
所需的软件包:
requests>=2.31.0——用于 Spotify Web API 的 HTTP 请求python-dotenv>=1.0.0——环境变量管理cairosvg>=2.7.0——将 SVG 转换为 PNG,用于图像生成pillow>=10.0.0——用于封面图创建的图像处理
💡 注意:
cairosvg和pillow软件包可启用图像生成功能,即使 Claude 无法原生生成图像,此技能也能创建封面图!
基本设置
初始化客户端最简单的方法是使用环境变量中的凭据(从 .env 文件加载):
from spotify_client import create_client_from_env
# Initialize client from environment variables (.env file)
client = create_client_from_env()
# If you have a refresh token, refresh the access token
if client.refresh_token:
client.refresh_access_token()
也可以手动提供凭据:
from spotify_client import SpotifyClient
# Initialize with credentials directly
client = SpotifyClient(
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET",
redirect_uri="http://localhost:8888/callback",
refresh_token="YOUR_REFRESH_TOKEN" # if available
)
# Refresh to get current access token
if client.refresh_token:
client.refresh_access_token()
常见操作
列出用户的所有播放列表(含分页):
# Get all playlists - handles pagination automatically
all_playlists = []
offset = 0
limit = 50 # Max allowed per request
while True:
playlists = client.get_user_playlists(limit=limit, offset=offset)
if not playlists:
break # No more playlists
all_playlists.extend(playlists)
offset += limit
if len(playlists) < limit:
break # Last page (fewer than limit returned)
print(f"Total playlists: {len(all_playlists)}")
for playlist in all_playlists:
print(f"- {playlist['name']} ({playlist['tracks']['total']} tracks)")
创建新播放列表:
playlist = client.create_playlist(
name="My Awesome Playlist",
description="A curated collection",
public=True
)
搜索曲目:
results = client.search_tracks(query="artist:The Beatles", limit=20)
向播放列表添加曲目:
client.add_tracks_to_playlist(
playlist_id="playlist_123",
track_ids=["track_1", "track_2", "track_3"]
)
播放列表管理工作流
列出用户的所有播放列表
重要: 用户的播放列表可能超过 50 个。务必使用分页获取所有播放列表:
# Get ALL playlists using pagination
all_playlists = []
offset = 0
limit = 50 # Spotify's max per request
while True:
batch = client.get_user_playlists(limit=limit, offset=offset)
if not batch:
break # No more playlists to fetch
all_playlists.extend(batch)
print(f"Fetched {len(batch)} playlists (total so far: {len(all_playlists)})")
offset += limit
if len(batch) < limit:
break # Last page - fewer results than limit means we're done
print(f"\n✓ Total playlists found: {len(all_playlists)}")
# Display all playlists with details
for i, playlist in enumerate(all_playlists, 1):
print(f"{i}. {playlist['name']}")
print(f" Tracks: {playlist['tracks']['total']}")
print(f" Public: {playlist['public']}")
print(f" ID: {playlist['id']}")
播放列表创建工作流
按艺人/乐队名称
创建包含特定艺人全部或大部分热门曲目的播放列表:
# STEP 1: Search for the artist by name
artists = client.search_artists(query="The Beatles", limit=1)
if not artists:
print("Artist not found")
# Handle error: artist doesn't exist or name is misspelled
else:
artist_id = artists[0]['id'] # Get Spotify ID of first result
# STEP 2: Get the artist's most popular tracks
# Note: Spotify API returns up to 10 top tracks per artist
tracks = client.get_artist_top_tracks(artist_id=artist_id)
track_ids = [t['id'] for t in tracks] # Extract just the track IDs
# STEP 3: Create a new playlist and add the tracks
playlist = client.create_playlist(name="The Beatles Collection")
client.add_tracks_to_playlist(playlist['id'], track_ids)
print(f"Created playlist with {len(track_ids)} tracks")
按主题/情绪
通过搜索符合情绪关键词的曲目来创建主题播放列表:
# STEP 1: Define search queries for your theme
# Spotify search syntax: "genre:indie mood:chill" or "genre:indie year:2020-2024"
theme_queries = [
"genre:indie mood:chill", # Search for chill indie tracks
"genre:indie year:2020-2024" # Search for recent indie tracks
]
# STEP 2: Search for tracks matching each query
all_tracks = []
for query in theme_queries:
results = client.search_tracks(query=query, limit=50) # Get up to 50 per query
all_tracks.extend(results) # Combine results from all queries
# STEP 3: Remove duplicates (same track may match multiple queries)
# Use set() with track IDs to keep only unique tracks
unique_track_ids = list(set(t['id'] for t in all_tracks))
# STEP 4: Create playlist with unique tracks (limit to 100 for reasonable size)
playlist = client.create_playlist(name="Chill Indie Evening")
client.add_tracks_to_playlist(playlist['id'], unique_track_ids[:100])
print(f"Created playlist with {len(unique_track_ids[:100])} tracks")
按歌词内容
使用 Spotify 的搜索功能查找具有特定歌词主题的曲目:
# STEP 1: Define keywords related to lyrical content
# Note: Spotify search indexes track/artist names and some metadata,
# not full lyrics, so results are based on title/description matching
queries = ["love", "heartbreak", "summer", "midnight"]
# STEP 2: Search for tracks matching each keyword
all_tracks = []
for keyword in queries:
results = client.search_tracks(query=keyword, limit=20) # 20 tracks per keyword
all_tracks.extend(results)
# STEP 3: Remove duplicates (same track may match multiple keywords)
# Use set() with track IDs to keep only unique tracks
unique_track_ids = list(set(t['id'] for t in all_tracks))
print(f"Found {len(all_tracks)} total matches, {len(unique_track_ids)} unique tracks")
# STEP 4: Create playlist (limit to 100 tracks for reasonable size)
playlist = client.create_playlist(name="Love & Heartbreak")
client.add_tracks_to_playlist(playlist['id'], unique_track_ids[:100])
print(f"Created playlist with {len(unique_track_ids[:100])} unique tracks")
根据指定歌曲列表
根据用户提供的曲目 URI 或搜索词列表创建播放列表:
# STEP 1: Get the list of songs from the user
# User provides song names (can also use Spotify URIs like "spotify:track:...")
song_list = ["Shape of You", "Blinding Lights", "As It Was"]
# STEP 2: Search for each song and collect track IDs
track_ids = []
for song_name in song_list:
results = client.search_tracks(query=song_name, limit=1) # Get best match
if results:
track_ids.append(results[0]['id']) # Add first result's ID
print(f"✓ Found: {results[0]['name']} by {results[0]['artists'][0]['name']}")
else:
print(f"✗ Not found: {song_name}") # Song doesn't exist or name is wrong
# STEP 3: Create playlist with found tracks
playlist = client.create_playlist(name="My Favorites")
if track_ids:
client.add_tracks_to_playlist(playlist['id'], track_ids)
print(f"Created playlist with {len(track_ids)}/{len(song_list)} tracks")
else:
print("No tracks found - playlist is empty")
🎨 封面图片生成
⚡ 独特功能:此技能可以生成图片!
Claude 无法原生生成图片,但此技能通过创建自定义 SVG 图形并将其转换为 PNG 图片,绕过了这一限制,可用于 Spotify 播放列表封面。
🚨 必须:使用封面 LLM 指南
⚠️ 在先阅读完整执行指南之前,请勿尝试生成封面图。
➡️ 请先阅读此文件:references/COVER_ART_LLM_GUIDE.md
此指南为必读内容,包含:
- 完整的分步执行说明
- 如何分析播放列表内容以确定合适的颜色
- 风格到颜色和情绪到颜色的映射表
- 字体规则和无障碍要求
- 边缘情况处理和质量检查清单
未经查阅此指南,请勿继续生成封面图。
⚠️ 上传所需权限范围
要将封面图上传到 Spotify,必须启用 ugc-image-upload 权限范围:
- 前往 Spotify Developer Dashboard
- 选择你的应用
- 确保授权中包含
ugc-image-upload权限范围 - 重新运行 OAuth 流程,以获取具有此权限范围的新刷新令牌:
python get_refresh_token.py - 使用新的刷新令牌更新
.env文件
没有此权限范围: 上传时会出现 401 错误。不过,你仍然可以在本地生成封面图片,再通过 Spotify 网页版或移动应用手动上传。
📖 遇到问题? 请参阅 COVER_ART_TROUBLESHOOTING.md,查看详细解决方案。
基本用法示例
⚠️ 请记住:生成封面图前,请阅读 references/COVER_ART_LLM_GUIDE.md!
from cover_art_generator import CoverArtGenerator
# Initialize generator (uses same credentials as SpotifyClient)
art_gen = CoverArtGenerator(client_id, client_secret, access_token)
# Generate and upload cover art
# (Follow the LLM guide for how to determine appropriate colors)
art_gen.create_and_upload_cover(
playlist_id=playlist['id'],
title="Beast Mode", # Main title (large text)
subtitle="Gym", # Optional subtitle
gradient_start="#E63946", # Colors determined from guide
gradient_end="#1D1D1D",
text_color="#FFFFFF"
)
所有封面图生成工作流、颜色选择指南和高级功能均记录在 references/COVER_ART_LLM_GUIDE.md 中。
高级操作
获取推荐
# Get AI-powered music recommendations based on seed artists/tracks/genres
recommendations = client.get_recommendations(
seed_artists=["artist_id_1"], # Spotify IDs of artists
seed_tracks=["track_id_1"], # Spotify IDs of tracks
limit=50 # Number of recommendations to get
)
# Returns: List of recommended tracks similar to the seeds
访问用户个人资料
# Get information about the current authenticated user
profile = client.get_current_user()
# Returns: user_id, display_name, email, followers, images, country, etc.
print(f"Logged in as: {profile['display_name']}")
print(f"User ID: {profile['id']}")
获取用户最常听的内容
# Get user's most played artists over different time periods
top_artists = client.get_top_items(
item_type="artists",
limit=20,
time_range="medium_term" # Options: short_term (~4 weeks), medium_term (~6 months), long_term (~years)
)
print(f"Top artist: {top_artists[0]['name']}")
# Get user's most played tracks
top_tracks = client.get_top_items(
item_type="tracks",
limit=20,
time_range="short_term" # Recent listening (last ~4 weeks)
)
print(f"Most played track: {top_tracks[0]['name']} by {top_tracks[0]['artists'][0]['name']}")
播放控制
# STEP 1: Start playback of a playlist or album
client.start_playback(
device_id="device_123", # Optional: specific device
context_uri="spotify:playlist:playlist_id", # What to play (playlist/album/artist URI)
offset=0 # Optional: start at track 0
)
# STEP 2: Pause playback
client.pause_playback(device_id="device_123")
# STEP 3: Skip to next track
client.next_track(device_id="device_123")
# STEP 4: Check what's currently playing
current = client.get_currently_playing()
if current and current.get('item'):
track = current['item']
print(f"Now playing: {track['name']} by {track['artists'][0]['name']}")
else:
print("Nothing is currently playing")
身份验证与凭据
有关 OAuth 流程设置和凭据管理的详细信息,请参阅 references/authentication_guide.md。确保凭据可通过环境变量获取,或在初始化时传入:
SPOTIFY_CLIENT_IDSPOTIFY_CLIENT_SECRETSPOTIFY_REDIRECT_URISPOTIFY_ACCESS_TOKEN(可选,可使用刷新令牌)SPOTIFY_REFRESH_TOKEN(用于刷新令牌)
API 参考
有关完整的 Spotify API 端点文档、速率限制、响应格式和错误处理模式,请参阅 references/api_reference.md。
脚本
spotify_client.py
用于执行所有 Spotify Web API 操作的综合 Python 封装。负责处理身份验证、令牌管理、速率限制,并提供以下方法:
- 身份验证和令牌刷新
- 播放列表的增删改查操作
- 搜索(曲目、艺人、专辑、播放列表)
- 曲目/URI 管理
- 用户数据访问
- 播放控制
- 推荐引擎
playlist_creator.py
用于从各种来源(艺人、主题、歌词、歌曲列表)智能创建播放列表的高级工具。封装常见工作流,并处理曲目去重和数量限制。
面向应用构建者(高级)
注意: 以下功能适用于构建 Web 应用的开发者,不适用于直接创建播放列表的任务。
如果用户要求你构建应用或导出数据,请参阅:
ADVANCED_USAGE.md- 应用开发模式scripts/export_data.py- 将 Spotify 数据导出为 JSONSpotifyAPIWrapper类 - 面向生产环境应用的错误处理
创建播放列表和管理音乐时,请使用上述工作流。