Reputation: 1
I am using Flask for my backend to gather spotify user tokens after a login in order to use this token data later in the app to automatically create playlists. The hangup here is that my callback seems to properly add token data to the session (print session in the /callback function returns the data I expect), however, once I try to access the session data in another function, such as generate_playlist, the session data (token) is empty, resulting in a failed playlist creation. Is there something I am missing/not returning in the callback function to get the session to properly retain the token data from /callback to be used in /generate playlist?
The prints in generate playlist only result in:
session in generate_playlist: <FileSystemSession {'_permanent': True}>
token_info: no session was set
Here is my app.py file:
from flask import Flask, request, redirect, session, jsonify, render_template
from flask_session import Session
from flask_cors import CORS
from dotenv import load_dotenv
import spotipy
from spotipy.oauth2 import SpotifyOAuth, SpotifyOauthError
from openai import OpenAI
import json
import os
print('app.py running')
load_dotenv()
app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(24)
app.config['SESSION_TYPE'] = 'filesystem'
app.config.from_object(__name__)
Session(app)
CORS(app, resources={r"/*": {"origins": "http://localhost:3000", "allow_headers": "*", "methods": ["GET", "POST", "OPTIONS"]}}, supports_credentials=True)
SPOTIFY_CLIENT_ID = os.getenv('SPOTIFY_CLIENT_ID')
SPOTIFY_CLIENT_SECRET = os.getenv('SPOTIFY_CLIENT_SECRET')
SPOTIFY_REDIRECT_URI = os.getenv('SPOTIFY_REDIRECT_URI')
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
# Set up Spotify authentication
oauth = SpotifyOAuth(
client_id=SPOTIFY_CLIENT_ID,
client_secret=SPOTIFY_CLIENT_SECRET,
redirect_uri=SPOTIFY_REDIRECT_URI,
scope='user-read-private user-read-email user-read-playback-state user-modify-playback-state user-read-recently-played user-top-read playlist-modify-public'
)
client = OpenAI(
api_key=os.environ['OPENAI_API_KEY'], # this is also the default, it can be omitted
)
@app.route('/')
def home():
return 'hello'
@app.route('/login')
def login():
auth_url = oauth.get_authorize_url()
return redirect(auth_url)
@app.route('/callback')
def callback():
session.clear()
code = request.args.get('code')
if code is None:
return redirect('http://localhost:3000?error=missing_code')
try:
token_info = oauth.get_access_token(code)
Session["token_info"] = token_info
print('cb session: ', Session)
return redirect('http://localhost:3000')
except SpotifyOauthError as e:
print('spotify oauth error')
return redirect(f'http://localhost:3000?error={str(e)}')
@app.route('/generate-playlist', methods=['POST', 'OPTIONS'])
def generate_playlist():
print('session in generate_playlist early: ', session)
if request.method == 'OPTIONS':
return '', 204
prompt = request.json['prompt']
# Use the OpenAI API to generate a playlist based on the prompt
print('creating openai')
openai_response = client.chat.completions.create(
model='gpt-4',
messages=[
{"role": "user", "content": f'Generate a playlist based on the following prompt and format into a JSON array of song name, song artist, and whether or not it is on spotify, example being [["One More Time", "Daft Punk", "Yes"], ["Aerodynamic", "Daft Punk", "Yes"]]: {prompt}'}
]
)
playlist_array = openai_response.choices[0].message.content.strip()
print('gen text: ', playlist_array)
playlist_data = json.loads(playlist_array)
print('pl: ', playlist_data)
print('session in generate_playlist: ', session) # Add this line to check the session
token_info = session.get("token_info", "no session was set")
print('token_info:', token_info)
if token_info is None:
print('Missing token')
return jsonify({'error': 'missing_token'}), 401
try:
sp = spotipy.Spotify(auth=token_info['access_token'])
track_ids = []
for track_info in playlist_data:
track_name, artist_name, on_spotify = track_info
if on_spotify.lower() == 'yes':
results = sp.search(q=f'track:{track_name} artist:{artist_name}', type='track', limit=1)
if results['tracks']['items']:
track_id = results['tracks']['items'][0]['id']
track_ids.append(track_id)
# Create a new playlist on Spotify
print('track ids: ', track_ids)
user_id = sp.current_user()['id']
playlist = sp.user_playlist_create(user_id, name=prompt, public=True)
# Add the tracks to the playlist
if track_ids:
print('adding track ids')
sp.user_playlist_add_tracks(user_id, playlist['id'], track_ids)
playlist_response = {
'name': playlist['name'],
'url': playlist['external_urls']['spotify'],
'tracks': [{'name': track_info[0], 'artist': track_info[1]} for track_info in playlist_data],
}
print('returning playlist data')
return jsonify(playlist_response)
except spotipy.SpotifyException as e:
print('Spotify API error:', e)
return jsonify({'error': 'spotify_api_error', 'message': str(e)}), 500
except Exception as e:
print('Error:', e)
return jsonify({'error': 'internal_server_error', 'message': str(e)}), 500
if __name__ == "__main__":
app.run(debug=True)
I am not getting any CORS errors in the frontend, so I do not believe cors is the issue here. Also, I am properly getting back the spotify login data/token after 'signing in' so it's not like the token is bad, I think. I tried adding a dummy value to the session with 'session["test"] = True' and that too is not storing properly between functions. My API calls to gpt-4 are working as well, so the issue is not there. This is why I'm led to believe it is purely a flask session issue.
Upvotes: 0
Views: 131
Reputation: 1
You can try this
token_info = session.get('token_info', None)
if not token_info:
return redirect("/login")
sp = spotipy.Spotify(auth=token_info['access_token'])
Upvotes: 0