Search code examples
pythonsessionweb-applicationsflasksession-state

Python Flask sessions data across clients is not separating


I am building a chat bot application on the web using Flask hosted on pythonanywhere.com However, when more than one person chats with the bot at the same time, their questions interfere with one another and the bot answers in the context of the most recent question.

I tried to separate the relevant data using sessions in Flask, but am seeing the same problems. I read the docs and have seen many examples using a username or email, but in my case I want to randomly generate a session ID and then have all of the relevant data for that user only pertain to their instance.

I know I need a secret key from this question I have a basic understanding the general usage from the documentation and other questions And i know it is best to stay away from global variables for these types of applications from this question

I thought each browser request would automatically separate the sessions and their data, but I must be missing something. I have posted the main portion of the code here. If my problem explanation is unclear you can see the problem at youngblksocrates.pythonanywhere.com by chatting with the bot from different browsers. Thanks so much!

from flask import Flask, request, url_for, render_template, session
import random
from user_info_object import UserInfo
from script_freeStyle import FreeStyleXXXX
import simplejson as json

app = Flask(__name__)
app.secret_key = "my secret key"

currentProfile = UserInfo() #helps bot know what the user has asked
learnBoutClass = FreeStyleXXXX() #conversation script to follow


greetings = ["HI","HEY","GREETINGS","HELLO","WASSUP", "WHAT UP"]

def preprocess(textblob):
    return str(textblob.correct())
def bot_reply_to_this(input,scriptobj):

    if input.upper() in greetings:
        reply = random.choice(["Hello!", "Hi", "Hey", "Greetings", "*Waves*","What's up?"])
    else:

        currentProfile = UserInfo()
        myspecificprofile = currentProfile.populate(session['profilestate'])
        responseAndProfile = scriptobj.determineReply(myspecificprofile,input)
        response = responseAndProfile[0]
        updatedprofile = responseAndProfile[1]
        session['lastrequestedinfo'] = scriptobj.lastRequestedInfo
        session['profilestate'] = json.dumps(updatedprofile.__dict__)
    return response

@app.route('/')
def user_chat_begins_fresh():

    sessionID = ''.join(random.choice('0123456789ABCDEF') for i in range(16))
    session.pop('ID',None)
    session['ID'] = sessionID
    session['lastrequestedinfo'] = ""
    #everything gotta start fresh
    takeClassScript.lastRequestedInfo = ""
    learnBoutClass.lastRequestedInfo = ""
    #create a new profile so that the state resets
    currentProfile = UserInfo()
    session['profilestate'] = json.dumps(currentProfile.__dict__)
    del chathistory [:]
    return render_template('init.html',urlToConversation=url_for('conversation_container'),inputVarName="input")

@app.route('/reply', methods=['POST'])
def conversation_container():
    rawinput = request.form["input"]
    session['input'] = rawinput
    blob_input = TextBlob(session['input'])
    cleaned_input = session['input']
    chosenscript = learnBoutClass
    session['lastrequestedinfo'] = chosenscript.lastRequestedInfo
    session['reply'] = bot_reply_to_this(session['input'],chosenscript)
    chathistory.append("You: " + session['input'] + "\n" )
    chathistory.append("Bot: " + session['reply'] + "\n" )
    printedhistory = "\n".join(chathistory)
    session['history'] = printedhistory

    return render_template('conversation.html',\
        output=session['history'] ,\
        urlToConversation=url_for('conversation_container'),\
        inputVarName="input",\
        urlToFreshChat=url_for('user_chat_begins_fresh'))

Thanks for your time & sorry for the wordy question!


Solution

  • I asked around and found out that if there are variables at the top level of the file, then they will get overwritten at every request.

    Since data is stored in the currentProfile and learnBoutClass variables I deleted those from the top level and replaced them with variables inside of the session dictionary: session['profiledata'] and session['scriptdata']

    This fixed the initial problem.