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!
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.