我正在使用spotipy使用python从Spotify检索一些曲目。因此,我收到令牌过期错误,我想刷新我的令牌。但我不明白如何从 spotipy 获取刷新令牌。
还有另一种刷新令牌或重新创建令牌的方法吗?
谢谢你。
Spotipy 使用访问令牌的粗略过程是:
prompt_for_user_token()
则将处理您在浏览器中完成 OAuth 流程,然后将其保存到缓存中。因此,如果您向 Spotipy 询问您的访问令牌(例如,使用prompt_for_user_token()
或通过直接设置SpotifyOAuth
对象)并且它之前已经缓存了访问令牌/刷新令牌,它将自动刷新。默认情况下,缓存位置应.cache-<username>
位于工作目录中,因此您可以在那里手动访问令牌。
如果您为 SpotipySpotify()
客户端提供auth
授权参数,它将无法自动刷新访问令牌,我认为它将在大约一个小时后过期。您可以client_credentials_manager
改为提供它,它将从中请求访问令牌。对象实现的唯一要求client_credentials_manager
是它提供了一个get_access_token()
不带参数并返回访问令牌的方法。
不久前我在 fork 中尝试过这个,这是对对象的修改以SpotifyOAuth
允许它充当 aclient_credentials_manager
并且这相当于prompt_for_user_token()
返回SpotifyOAuth
可以Spotify()
作为凭据管理器参数传递给 Spotipy 客户端的对象。
因为这个问题我花了一段时间才弄清楚,所以我将把我的解决方案放在这里。这适用于在服务器上永久运行 Spotipy(或至少在过去 12 小时内运行)。您必须在本地运行一次才能生成 .cache 文件,但是一旦发生这种情况,您的服务器就可以使用该缓存文件来更新它的访问令牌并在需要时刷新令牌。
import spotipy
scopes = 'ugc-image-upload user-read-playback-state user-modify-playback-state user-read-currently-playing ...'
sp = spotipy.Spotify(auth_manager=spotipy.SpotifyOAuth(scope=scopes))
while True:
try:
current_song = sp.currently_playing()
do something...
except spotipy.SpotifyOauthError as e:
sp = spotipy.Spotify(auth_manager=spotipy.SpotifyOAuth(scope=scopes))
我看到了mardiff的解决方案,它绝对有效,但我不喜欢它等待错误发生然后修复它,所以我找到了一个不需要捕获错误的解决方案,使用spotipy已经实现的方法。
import spotipy
from spotipy.oauth2 import SpotifyOAuth
import time
USERNAME = '...'
CLIENT_ID = '...'
CLIENT_SECRET = '...'
SCOPE = 'user-read-currently-playing'
def create_spotify():
auth_manager = SpotifyOAuth(
scope=SCOPE,
username=USERNAME,
redirect_uri='http://localhost:8080',
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET)
spotify = spotipy.Spotify(auth_manager=auth_manager)
return auth_manager, spotify
def refresh_spotify(auth_manager, spotify):
token_info = auth_manager.cache_handler.get_cached_token()
if auth_manager.is_token_expired(token_info):
auth_manager, spotify = create_spotify()
return auth_manager, spotify
if __name__ == '__main__':
auth_manager, spotify = create_spotify()
while True:
auth_manager, spotify = refresh_spotify(auth_manager, spotify)
playing = spotify.currently_playing()
if playing:
print(playing['item']['name'])
else:
print('Nothing is playing.')
time.sleep(30)
使用此方法,您可以在每次使用 spotify 对象之前检查令牌是否已过期(或在过期后 60 秒内)。根据需要创建新的 auth_manager 和 spotify 对象。