您说得对,Spotify会在添加令牌之前重定向您,从而结束该函数的执行。因此,您需要添加回调步骤,在重定向后获取身份验证令牌。
Spotipy的util.prompt_for_user_token方法不适用于Web服务器,因此最好自己实现认证流程,然后在获得令牌后使用Spotipy。幸运的是,Spotify授权流程非常简单易行。
方法1:自己实现认证流程:
from flask import Flask, render_template, redirect, request, session, make_response,session,redirect
import spotipy
import spotipy.util as util
from credentz import *
import requests
app = Flask(__name__)
app.secret_key = SSK
API_BASE = 'https://accounts.spotify.com'
REDIRECT_URI = "http://127.0.0.1:5000/api_callback"
SCOPE = 'playlist-modify-private,playlist-modify-public,user-top-read'
SHOW_DIALOG = True
@app.route("/")
def verify():
auth_url = f'{API_BASE}/authorize?client_id={CLI_ID}&response_type=code&redirect_uri={REDIRECT_URI}&scope={SCOPE}&show_dialog={SHOW_DIALOG}'
print(auth_url)
return redirect(auth_url)
@app.route("/index")
def index():
return render_template("index.html")
@app.route("/api_callback")
def api_callback():
session.clear()
code = request.args.get('code')
auth_token_url = f"{API_BASE}/api/token"
res = requests.post(auth_token_url, data={
"grant_type":"authorization_code",
"code":code,
"redirect_uri":"http://127.0.0.1:5000/api_callback",
"client_id":CLI_ID,
"client_secret":CLI_SEC
})
res_body = res.json()
print(res.json())
session["toke"] = res_body.get("access_token")
return redirect("index")
@app.route("/go", methods=['POST'])
def go():
data = request.form
sp = spotipy.Spotify(auth=session['toke'])
response = sp.current_user_top_artists(limit=data['num_tracks'], time_range=data['time_range'])
return render_template("results.html", data=data)
if __name__ == "__main__":
app.run(debug=True)
另一方面,我们可以有所作弊,使用spotipy自身正在使用的方法来节省我们的代码。
方法2:使用spotipy.oauth2.SpotifyOAuth方法实现授权流程(以及自定义令牌管理):
from flask import Flask, render_template, redirect, request, session, make_response,session,redirect
import spotipy
import spotipy.util as util
from credentz import *
import time
import json
app = Flask(__name__)
app.secret_key = SSK
API_BASE = 'https://accounts.spotify.com'
REDIRECT_URI = "http://127.0.0.1:5000/api_callback"
SCOPE = 'playlist-modify-private,playlist-modify-public,user-top-read'
SHOW_DIALOG = True
@app.route("/")
def verify():
sp_oauth = spotipy.oauth2.SpotifyOAuth(client_id = CLI_ID, client_secret = CLI_SEC, redirect_uri = REDIRECT_URI, scope = SCOPE)
auth_url = sp_oauth.get_authorize_url()
print(auth_url)
return redirect(auth_url)
@app.route("/index")
def index():
return render_template("index.html")
@app.route("/api_callback")
def api_callback():
sp_oauth = spotipy.oauth2.SpotifyOAuth(client_id = CLI_ID, client_secret = CLI_SEC, redirect_uri = REDIRECT_URI, scope = SCOPE)
session.clear()
code = request.args.get('code')
token_info = sp_oauth.get_access_token(code)
session["token_info"] = token_info
return redirect("index")
@app.route("/go", methods=['POST'])
def go():
session['token_info'], authorized = get_token(session)
session.modified = True
if not authorized:
return redirect('/')
data = request.form
sp = spotipy.Spotify(auth=session.get('token_info').get('access_token'))
response = sp.current_user_top_tracks(limit=data['num_tracks'], time_range=data['time_range'])
return render_template("results.html", data=data)
def get_token(session):
token_valid = False
token_info = session.get("token_info", {})
if not (session.get('token_info', False)):
token_valid = False
return token_info, token_valid
now = int(time.time())
is_token_expired = session.get('token_info').get('expires_at') - now < 60
if (is_token_expired):
sp_oauth = spotipy.oauth2.SpotifyOAuth(client_id = CLI_ID, client_secret = CLI_SEC, redirect_uri = REDIRECT_URI, scope = SCOPE)
token_info = sp_oauth.refresh_access_token(session.get('token_info').get('refresh_token'))
token_valid = True
return token_info, token_valid
if __name__ == "__main__":
app.run(debug=True)
在我看来,两种方法都是同样有效的,只要选择你更容易理解的方法即可。
确保在spotify应用程序仪表板中更新已授权的重定向URI。
有关更多信息,请参阅spotify文档:https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow