Nisus Imke
Nisus Imke

Reputation: 1

Flask Session is forgetting data between calls on backend that's being added to the session

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

Answers (1)

Tyler Weiss
Tyler Weiss

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

Related Questions