【发布时间】:2018-07-30 17:23:56
【问题描述】:
我正在使用 spotipy 使用 python 从 Spotify 检索一些曲目。因此,我收到令牌过期错误,我想刷新我的令牌。但我不明白如何从 spotipy 获取刷新令牌。
是否有另一种方法来刷新令牌或重新创建令牌?
谢谢。
【问题讨论】:
我正在使用 spotipy 使用 python 从 Spotify 检索一些曲目。因此,我收到令牌过期错误,我想刷新我的令牌。但我不明白如何从 spotipy 获取刷新令牌。
是否有另一种方法来刷新令牌或重新创建令牌?
谢谢。
【问题讨论】:
Sptipy 使用访问令牌的粗略过程是:
prompt_for_user_token() 将处理您在浏览器中完成 OAuth 流程,然后将其保存到缓存中。因此,如果您向 Spotipy 询问您的访问令牌(例如,使用 prompt_for_user_token() 或直接设置 SpotifyOAuth 对象)并且它之前已缓存访问令牌/刷新令牌,它将自动刷新。默认缓存位置应该是工作目录中的.cache-<username>,所以你可以在那里手动访问令牌。
如果您为 Spotipy Spotify() 客户端提供 auth 参数进行授权,它将无法自动刷新访问令牌,我认为它将在大约一个小时后过期。您可以改为提供client_credentials_manager,它将从中请求访问令牌。 client_credentials_manager 对象的实现的唯一要求是它提供了一个 get_access_token() 方法,该方法不接受任何参数并返回一个访问令牌。
我不久前在一个分支中尝试了这个,here's the modification to the SpotifyOAuth object 允许它充当client_credentials_manager 和here's the equivalent of prompt_for_user_token(),返回您可以传递给 Spotipy Spotify() 客户端的 SpotifyOAuth 对象作为凭据管理器参数。
【讨论】:
client.py, line 92, in _auth_headers token = self.client_credentials_manager.get_access_token() TypeError: get_access_token() missing 1 required positional argument: 'code'。你知道为什么会这样吗?
因为这个问题我花了一段时间才弄清楚,所以我将把我的解决方案放在这里。这适用于在服务器上永久运行 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 对象。
【讨论】: