[GH-ISSUE #35] I've been having a persistent issue, and I don't know how to fix it #20

Closed
opened 2026-02-27 19:06:28 +03:00 by kerem · 4 comments
Owner

Originally created by @RhowindMacDermott on GitHub (Jun 28, 2025).
Original GitHub issue: https://github.com/Aran404/SpotAPI/issues/35

Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
:5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)

Originally created by @RhowindMacDermott on GitHub (Jun 28, 2025). Original GitHub issue: https://github.com/Aran404/SpotAPI/issues/35 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) :5000/api/playlists:1 Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)
kerem closed this issue 2026-02-27 19:06:28 +03:00
Author
Owner

@Aran404 commented on GitHub (Jun 30, 2025):

Could you provide code?

<!-- gh-comment-id:3021124353 --> @Aran404 commented on GitHub (Jun 30, 2025): Could you provide code?
Author
Owner

@RhowindMacDermott commented on GitHub (Jul 1, 2025):

Sorry I've been super busy and tired going to sleep at 2 AM in the morning and waking up at 2 PM here's the code
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
import traceback
from flask import Flask, render_template, request, jsonify
from spotapi.login import Login, Config, LoginError # Import LoginError
from spotapi.playlist import PrivatePlaylist
from spotapi.http.request import TLSClient
from spotapi.utils.saver import JSONSaver # Import JSONSaver
from spotapi.utils.logger import NoopLogger # Import NoopLogger
from spotapi.types.interfaces import CaptchaProtocol # Import CaptchaProtocol

Define a dummy solver that does nothing but returns a non-empty string

class DummySolver(CaptchaProtocol):
def init(self, *args, **kwargs):
pass

def solve_captcha(self, *args, **kwargs) -> str:
    return "dummy_captcha_response" # Return a non-empty string

app = Flask(name)

@app.route('/')
def index():
return render_template('index.html')

def get_login_instance(auth_data, auth_method):
cfg = Config(logger=NoopLogger())
cfg.client = TLSClient("chrome_120", "", auto_retries=3)
cfg.saver = JSONSaver()

if auth_method == 'cookies':
    cookies_str = auth_data['cookies']
    # Manually parse and de-duplicate cookies, keeping the last value for each key
    parsed_cookies = {}
    for cookie_part in cookies_str.split(';'):
        cookie_part = cookie_part.strip()
        if not cookie_part:
            continue

        parts = cookie_part.split('=', 1)
        if len(parts) == 2:
            k, v = parts[0], parts[1]
            parsed_cookies[k] = v
        elif len(parts) == 1:
            k = parts[0]
            parsed_cookies[k] = ""

    # Reconstruct the cookie string from the de-duplicated dictionary
    deduplicated_cookies_str = "; ".join([f"{k}={v}" for k, v in parsed_cookies.items()])
    return Login.from_cookies({"identifier": "user", "cookies": deduplicated_cookies_str}, cfg)
elif auth_method == 'email_password':
    email = auth_data['email']
    password = auth_data['password']
    cfg.solver = DummySolver() # Assign the dummy solver
    login_instance = Login(cfg, password, email=email)
    try:
        login_instance.login() # Perform the login
    except LoginError as e:
        # Print the detailed error string from SpotAPI if available
        if hasattr(e, 'error') and e.error:
            print(f"SpotAPI Login Error Details: {e.error}")
        raise # Re-raise the exception to be caught by the outer try-except
    return login_instance
else:
    raise ValueError("Invalid authentication method")

@app.route('/api/playlists', methods=['POST'])
def get_playlists():
auth_data = request.json
auth_method = auth_data.get('auth_method')

if not auth_method:
    return jsonify({'error': 'Authentication method is required'}), 400

try:
    print("Attempting to get playlists...") # Added for debugging
    login = get_login_instance(auth_data, auth_method)
    private_playlist = PrivatePlaylist(login)
    library = private_playlist.get_library()

    playlists = []
    for item in library['data']['me']['library']['items']:
        if item['uri'].startswith('spotify:playlist:'):
            playlists.append({
                'name': item['name'],
                'uri': item['uri']
            })
    
    playlists.insert(0, {
        'name': 'Liked Songs',
        'uri': 'spotify:user:spotify:collection'
    })

    return jsonify(playlists)

except Exception as e:
    print("Error in /api/playlists:") # Added for debugging
    traceback.print_exc() # This will print the full traceback to the terminal
    error_details = str(e) # Only send the error message to the frontend
    return jsonify({'error': error_details}), 500

@app.route('/api/recommendations', methods=['POST'])
def get_recommendations():
auth_data = request.json
auth_method = auth_data.get('auth_method')
playlist_uri = auth_data.get('playlist_uri')

if not auth_method or not playlist_uri:
    return jsonify({'error': 'Authentication method and playlist URI are required'}), 400

try:
    print("Attempting to get recommendations...") # Added for debugging
    login = get_login_instance(auth_data, auth_method)
    private_playlist = PrivatePlaylist(login, playlist=playlist_uri)
    recommendations = private_playlist.recommended_songs()

    return jsonify(recommendations)

except Exception as e:
    print("Error in /api/recommendations:") # Added for debugging
    traceback.print_exc() # This will print the full traceback to the terminal
    error_details = str(e) # Only send the error message to the frontend
    return jsonify({'error': error_details}), 500

if name == 'main':
app.run(debug=True)

<!-- gh-comment-id:3025574827 --> @RhowindMacDermott commented on GitHub (Jul 1, 2025): Sorry I've been super busy and tired going to sleep at 2 AM in the morning and waking up at 2 PM here's the code -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= import traceback from flask import Flask, render_template, request, jsonify from spotapi.login import Login, Config, LoginError # Import LoginError from spotapi.playlist import PrivatePlaylist from spotapi.http.request import TLSClient from spotapi.utils.saver import JSONSaver # Import JSONSaver from spotapi.utils.logger import NoopLogger # Import NoopLogger from spotapi.types.interfaces import CaptchaProtocol # Import CaptchaProtocol # Define a dummy solver that does nothing but returns a non-empty string class DummySolver(CaptchaProtocol): def __init__(self, *args, **kwargs): pass def solve_captcha(self, *args, **kwargs) -> str: return "dummy_captcha_response" # Return a non-empty string app = Flask(__name__) @app.route('/') def index(): return render_template('index.html') def get_login_instance(auth_data, auth_method): cfg = Config(logger=NoopLogger()) cfg.client = TLSClient("chrome_120", "", auto_retries=3) cfg.saver = JSONSaver() if auth_method == 'cookies': cookies_str = auth_data['cookies'] # Manually parse and de-duplicate cookies, keeping the last value for each key parsed_cookies = {} for cookie_part in cookies_str.split(';'): cookie_part = cookie_part.strip() if not cookie_part: continue parts = cookie_part.split('=', 1) if len(parts) == 2: k, v = parts[0], parts[1] parsed_cookies[k] = v elif len(parts) == 1: k = parts[0] parsed_cookies[k] = "" # Reconstruct the cookie string from the de-duplicated dictionary deduplicated_cookies_str = "; ".join([f"{k}={v}" for k, v in parsed_cookies.items()]) return Login.from_cookies({"identifier": "user", "cookies": deduplicated_cookies_str}, cfg) elif auth_method == 'email_password': email = auth_data['email'] password = auth_data['password'] cfg.solver = DummySolver() # Assign the dummy solver login_instance = Login(cfg, password, email=email) try: login_instance.login() # Perform the login except LoginError as e: # Print the detailed error string from SpotAPI if available if hasattr(e, 'error') and e.error: print(f"SpotAPI Login Error Details: {e.error}") raise # Re-raise the exception to be caught by the outer try-except return login_instance else: raise ValueError("Invalid authentication method") @app.route('/api/playlists', methods=['POST']) def get_playlists(): auth_data = request.json auth_method = auth_data.get('auth_method') if not auth_method: return jsonify({'error': 'Authentication method is required'}), 400 try: print("Attempting to get playlists...") # Added for debugging login = get_login_instance(auth_data, auth_method) private_playlist = PrivatePlaylist(login) library = private_playlist.get_library() playlists = [] for item in library['data']['me']['library']['items']: if item['uri'].startswith('spotify:playlist:'): playlists.append({ 'name': item['name'], 'uri': item['uri'] }) playlists.insert(0, { 'name': 'Liked Songs', 'uri': 'spotify:user:spotify:collection' }) return jsonify(playlists) except Exception as e: print("Error in /api/playlists:") # Added for debugging traceback.print_exc() # This will print the full traceback to the terminal error_details = str(e) # Only send the error message to the frontend return jsonify({'error': error_details}), 500 @app.route('/api/recommendations', methods=['POST']) def get_recommendations(): auth_data = request.json auth_method = auth_data.get('auth_method') playlist_uri = auth_data.get('playlist_uri') if not auth_method or not playlist_uri: return jsonify({'error': 'Authentication method and playlist URI are required'}), 400 try: print("Attempting to get recommendations...") # Added for debugging login = get_login_instance(auth_data, auth_method) private_playlist = PrivatePlaylist(login, playlist=playlist_uri) recommendations = private_playlist.recommended_songs() return jsonify(recommendations) except Exception as e: print("Error in /api/recommendations:") # Added for debugging traceback.print_exc() # This will print the full traceback to the terminal error_details = str(e) # Only send the error message to the frontend return jsonify({'error': error_details}), 500 if __name__ == '__main__': app.run(debug=True)
Author
Owner

@RhowindMacDermott commented on GitHub (Jul 1, 2025):

Here's the code import traceback
from flask import Flask, render_template, request, jsonify
from spotapi.login import Login, Config, LoginError # Import LoginError
from spotapi.playlist import PrivatePlaylist
from spotapi.http.request import TLSClient
from spotapi.utils.saver import JSONSaver # Import JSONSaver
from spotapi.utils.logger import NoopLogger # Import NoopLogger
from spotapi.types.interfaces import CaptchaProtocol # Import CaptchaProtocol

Define a dummy solver that does nothing but returns a non-empty string

class DummySolver(CaptchaProtocol):
def init(self, *args, **kwargs):
pass

def solve_captcha(self, *args, **kwargs) -> str:
    return "dummy_captcha_response" # Return a non-empty string

app = Flask(name)

@app.route('/')
def index():
return render_template('index.html')

def get_login_instance(auth_data, auth_method):
cfg = Config(logger=NoopLogger())
cfg.client = TLSClient("chrome_120", "", auto_retries=3)
cfg.saver = JSONSaver()

if auth_method == 'cookies':
    cookies_str = auth_data['cookies']
    # Manually parse and de-duplicate cookies, keeping the last value for each key
    parsed_cookies = {}
    for cookie_part in cookies_str.split(';'):
        cookie_part = cookie_part.strip()
        if not cookie_part:
            continue

        parts = cookie_part.split('=', 1)
        if len(parts) == 2:
            k, v = parts[0], parts[1]
            parsed_cookies[k] = v
        elif len(parts) == 1:
            k = parts[0]
            parsed_cookies[k] = ""

    # Reconstruct the cookie string from the de-duplicated dictionary
    deduplicated_cookies_str = "; ".join([f"{k}={v}" for k, v in parsed_cookies.items()])
    return Login.from_cookies({"identifier": "user", "cookies": deduplicated_cookies_str}, cfg)
elif auth_method == 'email_password':
    email = auth_data['email']
    password = auth_data['password']
    cfg.solver = DummySolver() # Assign the dummy solver
    login_instance = Login(cfg, password, email=email)
    try:
        login_instance.login() # Perform the login
    except LoginError as e:
        # Print the detailed error string from SpotAPI if available
        if hasattr(e, 'error') and e.error:
            print(f"SpotAPI Login Error Details: {e.error}")
        raise # Re-raise the exception to be caught by the outer try-except
    return login_instance
else:
    raise ValueError("Invalid authentication method")

@app.route('/api/playlists', methods=['POST'])
def get_playlists():
auth_data = request.json
auth_method = auth_data.get('auth_method')

if not auth_method:
    return jsonify({'error': 'Authentication method is required'}), 400

try:
    print("Attempting to get playlists...") # Added for debugging
    login = get_login_instance(auth_data, auth_method)
    private_playlist = PrivatePlaylist(login)
    library = private_playlist.get_library()

    playlists = []
    for item in library['data']['me']['library']['items']:
        if item['uri'].startswith('spotify:playlist:'):
            playlists.append({
                'name': item['name'],
                'uri': item['uri']
            })
    
    playlists.insert(0, {
        'name': 'Liked Songs',
        'uri': 'spotify:user:spotify:collection'
    })

    return jsonify(playlists)

except Exception as e:
    print("Error in /api/playlists:") # Added for debugging
    traceback.print_exc() # This will print the full traceback to the terminal
    error_details = str(e) # Only send the error message to the frontend
    return jsonify({'error': error_details}), 500

@app.route('/api/recommendations', methods=['POST'])
def get_recommendations():
auth_data = request.json
auth_method = auth_data.get('auth_method')
playlist_uri = auth_data.get('playlist_uri')

if not auth_method or not playlist_uri:
    return jsonify({'error': 'Authentication method and playlist URI are required'}), 400

try:
    print("Attempting to get recommendations...") # Added for debugging
    login = get_login_instance(auth_data, auth_method)
    private_playlist = PrivatePlaylist(login, playlist=playlist_uri)
    recommendations = private_playlist.recommended_songs()

    return jsonify(recommendations)

except Exception as e:
    print("Error in /api/recommendations:") # Added for debugging
    traceback.print_exc() # This will print the full traceback to the terminal
    error_details = str(e) # Only send the error message to the frontend
    return jsonify({'error': error_details}), 500

if name == 'main':
app.run(debug=True)

<!-- gh-comment-id:3025576452 --> @RhowindMacDermott commented on GitHub (Jul 1, 2025): Here's the code import traceback from flask import Flask, render_template, request, jsonify from spotapi.login import Login, Config, LoginError # Import LoginError from spotapi.playlist import PrivatePlaylist from spotapi.http.request import TLSClient from spotapi.utils.saver import JSONSaver # Import JSONSaver from spotapi.utils.logger import NoopLogger # Import NoopLogger from spotapi.types.interfaces import CaptchaProtocol # Import CaptchaProtocol # Define a dummy solver that does nothing but returns a non-empty string class DummySolver(CaptchaProtocol): def __init__(self, *args, **kwargs): pass def solve_captcha(self, *args, **kwargs) -> str: return "dummy_captcha_response" # Return a non-empty string app = Flask(__name__) @app.route('/') def index(): return render_template('index.html') def get_login_instance(auth_data, auth_method): cfg = Config(logger=NoopLogger()) cfg.client = TLSClient("chrome_120", "", auto_retries=3) cfg.saver = JSONSaver() if auth_method == 'cookies': cookies_str = auth_data['cookies'] # Manually parse and de-duplicate cookies, keeping the last value for each key parsed_cookies = {} for cookie_part in cookies_str.split(';'): cookie_part = cookie_part.strip() if not cookie_part: continue parts = cookie_part.split('=', 1) if len(parts) == 2: k, v = parts[0], parts[1] parsed_cookies[k] = v elif len(parts) == 1: k = parts[0] parsed_cookies[k] = "" # Reconstruct the cookie string from the de-duplicated dictionary deduplicated_cookies_str = "; ".join([f"{k}={v}" for k, v in parsed_cookies.items()]) return Login.from_cookies({"identifier": "user", "cookies": deduplicated_cookies_str}, cfg) elif auth_method == 'email_password': email = auth_data['email'] password = auth_data['password'] cfg.solver = DummySolver() # Assign the dummy solver login_instance = Login(cfg, password, email=email) try: login_instance.login() # Perform the login except LoginError as e: # Print the detailed error string from SpotAPI if available if hasattr(e, 'error') and e.error: print(f"SpotAPI Login Error Details: {e.error}") raise # Re-raise the exception to be caught by the outer try-except return login_instance else: raise ValueError("Invalid authentication method") @app.route('/api/playlists', methods=['POST']) def get_playlists(): auth_data = request.json auth_method = auth_data.get('auth_method') if not auth_method: return jsonify({'error': 'Authentication method is required'}), 400 try: print("Attempting to get playlists...") # Added for debugging login = get_login_instance(auth_data, auth_method) private_playlist = PrivatePlaylist(login) library = private_playlist.get_library() playlists = [] for item in library['data']['me']['library']['items']: if item['uri'].startswith('spotify:playlist:'): playlists.append({ 'name': item['name'], 'uri': item['uri'] }) playlists.insert(0, { 'name': 'Liked Songs', 'uri': 'spotify:user:spotify:collection' }) return jsonify(playlists) except Exception as e: print("Error in /api/playlists:") # Added for debugging traceback.print_exc() # This will print the full traceback to the terminal error_details = str(e) # Only send the error message to the frontend return jsonify({'error': error_details}), 500 @app.route('/api/recommendations', methods=['POST']) def get_recommendations(): auth_data = request.json auth_method = auth_data.get('auth_method') playlist_uri = auth_data.get('playlist_uri') if not auth_method or not playlist_uri: return jsonify({'error': 'Authentication method and playlist URI are required'}), 400 try: print("Attempting to get recommendations...") # Added for debugging login = get_login_instance(auth_data, auth_method) private_playlist = PrivatePlaylist(login, playlist=playlist_uri) recommendations = private_playlist.recommended_songs() return jsonify(recommendations) except Exception as e: print("Error in /api/recommendations:") # Added for debugging traceback.print_exc() # This will print the full traceback to the terminal error_details = str(e) # Only send the error message to the frontend return jsonify({'error': error_details}), 500 if __name__ == '__main__': app.run(debug=True)
Author
Owner

@RhowindMacDermott commented on GitHub (Jul 1, 2025):

I accidetinally hit close

<!-- gh-comment-id:3025578154 --> @RhowindMacDermott commented on GitHub (Jul 1, 2025): I accidetinally hit close
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/SpotAPI#20
No description provided.