Forums

Getting 502-backend/OS Write error when trying to return redirect_url, however doing return_template works

When i try calling my artistFunction it will give me an error if I dont return a rendered_template. In the call before, i return a redirect_url and the function doesnt give a error so I am confused as to why artist does when I follow the same syntax. I dont get why I am getting an OSError when all I'm trying to do is commit the data to a database

Error when trying to call return redirect_url:

2021-04-23 22:42:40,482: OSError: write error

Function call order:

addUserFun()
addArtistFun()
addSongFun()

Code:

# A very simple Flask Hello World app for you to get started with...

import os
import string
import random
import json
import urllib
# from pysnap import Snapchat
import time

from flask import Flask, render_template, request, session, make_response, url_for, redirect
from data import getBasicInfo, countArtistsDesc, countSongsDesc, getHighestPlayedDays, getPlaylist, countSongsFull, countArtists
from spotifyApiGrabber import getSong, getArtist, getBigArtist, getBigSong
from werkzeug.utils import secure_filename

from instagrapi import Client
from instagrapi.types import Location, StoryMention, StoryLocation, StoryLink, StoryHashtag
from instagrapi.story import StoryBuilder

from sqlalchemy import Table, Column, Integer, ForeignKey, String, create_engine
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.sql import func

import datetime
import math
import array

from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw

app = Flask(__name__)
app.secret_key = "SECRET_KEY"

ALLOWED_EXTENSIONS = {'json'}

shArray = []
testFile = ""
artistDict = {}
songDict = {}
albumDict = {}

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

SQLALCHEMY_DATABASE_URI = "mysql+mysqlconnector://{username}:{password}@{hostname}/{databasename}".format(
    username="Spotify365",
    password="A$troworld85",
    hostname="Spotify365.mysql.pythonanywhere-services.com",
    databasename="Spotify365$Spotify365DB",
)
app.config["SQLALCHEMY_DATABASE_URI"] = SQLALCHEMY_DATABASE_URI
app.config["SQLALCHEMY_POOL_RECYCLE"] = 600
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

Base = declarative_base()
engine = create_engine(SQLALCHEMY_DATABASE_URI, echo=True)
Session = sessionmaker(bind=engine)
dbSession = Session()

class User(Base):
    __tablename__ = "Users"
    id = Column(Integer, primary_key=True)
    username = Column(String(100))
    basicInfo = relationship("UserInfo")
    artistLibrary = relationship("Artist")
    songLibrary = relationship("Song")
    albumLibrary = relationship("Album")
    def __repr__(self):
        return '<User %r, %s>' % (self.id, self.username)

class Artist(Base):
    __tablename__ = "Artist_Library"
    id = Column(Integer, primary_key=True)
    artistName = Column(String(100))
    time_played = Column(String(100))
    clicks = Column(String(100))
    songLibrary = relationship("Song")
    albumLibrary = relationship("Album")
    user_id = Column(Integer, ForeignKey('Users.id'))
    artist_uri = Column(String(100))
    # def __repr__(self):
        # return '<Artist %r, %s, %r, %s>' % (self.id, self.artistName, self.time_played, self.artist_uri)


class Song(Base):
    __tablename__ = "Song_Library"
    id = Column(Integer, primary_key=True)
    trackName = Column(String(100))
    artist = Column(String(100))
    albumName = Column(String(100))
    time_played = Column(String(100))
    clicks = Column(String(100))
    user_id = Column(Integer, ForeignKey('Users.id'))
    artist_id = Column(Integer, ForeignKey('Artist_Library.id'))
    song_uri = Column(String(100))
    # def __repr__(self):
        # return '<Song %r, %s, %s, %s, %r, %r, %r, %s>' % (self.id, self.trackName, self.artist, self.time_played, self.clicks, self.user_id, self.artist_id, self.song_uri)

class Album(Base):
    __tablename__ = "Album_Library"
    id = Column(Integer, primary_key=True)
    albumName = Column(String(100))
    artist = Column(String(100))
    time_played = Column(String(100))
    clicks = Column(String(100))
    user_id = Column(Integer, ForeignKey('Users.id'))
    artist_id = Column(Integer, ForeignKey('Artist_Library.id'))
    album_uri = Column(String(100))

class UserInfo(Base):
    __tablename__ = "User_Info"
    id = Column(Integer, primary_key=True)
    spotifyUn = Column(String(100))
    spotifyDn = Column(String(100))
    spotifyCD = Column(String(100))
    numFwr = Column(Integer)
    numFol = Column(Integer)
    nP = Column(Integer)
    dL = Column(String(100))
    nOS = Column(Integer)
    tL = Column(String(100))
    user_id = Column(Integer, ForeignKey('Users.id'))


def createDB():
    Base.metadata.create_all(engine, checkfirst=True)

@app.route('/addUserIFun/<un>')
def addUserIFun(un):
    session["username"] = str(un)

    bi = json.loads(getBasicInfo(un))

    # pNameList = []
    spotifyUser = bi["Username"]
    displayName = bi["Display Name"]
    accountCreationDate = bi["Account Creation Date"]
    following = bi["Following"]
    followers = bi["Followers"]
    playlistCount = bi["Number of playlists"]

    timeStamp = bi["Data Lifecycle"]
    totalNumberSongs = bi["Total Number of Songs Analyzed"]

    sessionUserId = dbSession.query(User.id).filter_by(username=un).scalar()
    totalTimeListened = dbSession.query(func.sum(Song.time_played)).filter(Song.user_id == sessionUserId).scalar()
    randomVariable = str(totalTimeListened)

    usersBI = UserInfo(spotifyUn=spotifyUser, spotifyDn=displayName, spotifyCD=accountCreationDate, numFwr=followers, numFol=following, nP=playlistCount, dL=timeStamp, nOS=totalNumberSongs, tL=randomVariable, user_id = sessionUserId)
    try:
        dbSession.add(usersBI)
        dbSession.commit()
    except:
        dbSession.rollback()
        dbSession.add(usersBI)
        dbSession.commit()
    resp = make_response(render_template('upload.html'))
    resp.set_cookie('userID', session['username'])
    return resp

@app.route('/addAlbumFun/<id>/<un>')
def addAlbumFun(id, un):
    global albumDict
    sortedAlbumList = dict(sorted(albumDict.items(), key=lambda item: item[1][1], reverse=True))
    finalAlbumList = list(sortedAlbumList.items())
    for i in range(0, len(finalAlbumList)):
        addAlbum(str(finalAlbumList[i][0]), str(finalAlbumList[i][1][0]), str(finalAlbumList[i][1][1]), str(finalAlbumList[i][1][2]), str(finalAlbumList[i][1][3]), id)
    return redirect(url_for('addUserIFun', un=un))

@app.route('/addSongFun/<songList>/<id>/<un>')
def addSongFun(songList, id, un):
    sortedSList = dict(sorted(songList.items(), key=lambda item: item[1][1], reverse=True))
    finalSList = list(sortedSList.items())
    global albumDict
    finalSList = songList
    for i in range(0, len(finalSList)):
        songName = finalSList[i][0]
        artistName = finalSList[i][1][0]
        tP = finalSList[i][1][1]
        tC = finalSList[i][1][2]
        songResponse = list(json.loads(getSong(artistName, songName)))
        albumName = str(songResponse[0])
        uri = songResponse[1]
        addSong(songName, artistName, albumName, tP, tC, uri, id)

        if albumName not in albumDict.keys():
            albumDict.update({albumName: [artistName, int(tP), int(tC), uri]})
        else:
            albumDict[albumName][1] += int(tP)
            albumDict[albumName][2] += int(tC)
    return redirect(url_for('addAlbumFun', id = id, un=un))

@app.route('/addArtistFun/<un>/<id>')
def addArtistFun(un, id):
    global shArray
    shArray.clear()
    un = un
    prefixed = [filename for filename in os.listdir('/home/Spotify365/mysite/users/' + str(un) + '/json') if filename.startswith("StreamingHistory")]
    for a in range(0, len(prefixed)):
        with open('/home/Spotify365/mysite/users/' + str(un) + '/json/StreamingHistory' + str(a) + ".json", encoding="utf8") as f:
            shArray.append(json.load(f))

    global songDict
    global artistDict
    global albumDict
    artistDict = {}
    songDict = {}                               # MS Played
    albumDict = {}
    for i in range(0, len(shArray)):
        for j in range(0, len(shArray[i])):  # For every song
            # if shArray[i][j]['trackName'] == "Vintage Chanel (feat. Joey Bada$$, Kirk Knight, Meechy Darko & Zombie Juice)":
                # shArray[i][j]['trackName'] = "Vintage Chanel (feat. Joey Badass, Kirk Knight, Meechy Darko & Zombie Juice)"
            trackName = shArray[i][j]['trackName']
            artistName = shArray[i][j]['artistName']
            timePlayed = int(shArray[i][j]['msPlayed'])
            if shArray[i][j]['artistName'] in artistDict:
                artistDict[artistName][0] += shArray[i][j]['msPlayed']
                artistDict[artistName][1] += 1
            else:
                artistDict.update({artistName: [timePlayed, 1]})
            if trackName not in songDict:
                songDict.update({trackName: [artistName, int(timePlayed), 1]})
            else:
                songDict[trackName][1] += int(timePlayed)
                # Add 1 to the number of clicks
                songDict[trackName][2] += 1
    sortedAList = dict(sorted(artistDict.items(), key=lambda item: item[1], reverse=True))
    finalAList = list(sortedAList.items())

    for i in range(0, len(finalAList)):
        aN = finalAList[i][0]
        tP = finalAList[i][1][0]
        tC = finalAList[i][1][1]
        uri = getArtist(finalAList[i][0])
        createdArtist = Artist(artistName = aN, time_played = tP, clicks = tC, artist_uri=uri, user_id = id)
        try:
            dbSession.add(createdArtist)
            dbSession.commit()
        except:
            dbSession.rollback()
            dbSession.add(createdArtist)
            dbSession.commit()

    # return redirect(url_for('addSongFun', songList=songDict, id=id, un=un))
    return render_template('upload.html')

@app.route('/addUserFun')
def addUserFun():
    # dbSession.rollback()

    # Create a new user and add their basic info
    un = session["username"]
    user = User(username = un)

    # Add user's listening history to the database
    try:
        dbSession.add(user)
        dbSession.commit()
    except:
        dbSession.rollback()
        dbSession.add(user)
        dbSession.commit()
    return redirect(url_for('addArtistFun', un=user.username, id=user.id))

I really don't understand what the issue is. What is calling the functions in that order? There are a number of redirect calls in the code that you dumped. Which one is the one that is causing the issue and what is actually happening when you're using it?