from flask import Flask, session, redirect, request, url_for
import requests
import os
import urllib.parse
app = Flask(__name__)
app.secret_key = os.urandom(24)
CLIENT_ID = "my-client-id"
CLIENT_SECRET = "my-client-secret"
REDIRECT_URI = "https://example.ngrok-free.app/callback"
API_BASE_URL = "https://api.spotify.com/v1"
AUTH_URL = "https://accounts.spotify.com/authorize"
TOKEN_URL = "https://accounts.spotify.com/api/token"
SCOPE = "user-top-read user-read-private user-read-email user-read-playback-state user-read-currently-playing"
@app.route("/")
def index():
return '<a href="/login">Login with Spotify</a>'
@app.route("/login")
def login():
params = {
"client_id": CLIENT_ID,
"response_type": "code",
"redirect_uri": REDIRECT_URI,
"scope": SCOPE,
}
return redirect(AUTH_URL + "?" + urllib.parse.urlencode(params))
@app.route("/callback")
def callback():
code = request.args.get("code")
if not code:
return "Authorization failed."
data = {
"grant_type": "authorization_code",
"code": code,
"redirect_uri": REDIRECT_URI,
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
}
headers = {"Content-Type": "application/x-www-form-urlencoded"}
res = requests.post(TOKEN_URL, data=data, headers=headers)
if res.status_code != 200:
return f"Token fetch failed: {res.text}"
session["access_token"] = res.json()["access_token"]
return redirect("/analyze")
@app.route("/analyze")
def analyze():
access_token = session.get("access_token")
if not access_token:
return redirect(url_for("login"))
headers = {"Authorization": f"Bearer {access_token}"}
# Fetch top tracks
top_tracks_res = requests.get(f"{API_BASE_URL}/me/top/tracks?limit=10", headers=headers)
if top_tracks_res.status_code != 200:
return f"Top tracks fetch failed: {top_tracks_res.status_code}"
track_ids = [track["id"] for track in top_tracks_res.json().get("items", [])]
# Fetch audio features
audio_features_res = requests.get(
f"{API_BASE_URL}/audio-features",
headers=headers,
params={"ids": ",".join(track_ids)},
)
print("Request URL:", audio_features_res.url)
print("Status:", audio_features_res.status_code)
print("Text:", audio_features_res.text)
if audio_features_res.status_code != 200:
return f"Audio features fetch failed: {audio_features_res.status_code} {audio_features_res.text}"
return "Audio features retrieved successfully."
if __name__ == "__main__":
app.run(debug=True)