【问题标题】:Python Flask sessions data across clients is not separating跨客户端的 Python Flask 会话数据没有分离
【发布时间】:2017-01-31 06:06:34
【问题描述】:

我正在使用托管在 pythonanywhere.com 上的 Flask 在网络上构建一个聊天机器人应用程序但是,当多人同时与该机器人聊天时,他们的问题会相互干扰,并且机器人会在以下情况下回答最近的问题。

我尝试使用 Flask 中的会话来分离相关数据,但遇到了同样的问题。我阅读了文档并看到了许多使用用户名或电子邮件的示例,但就我而言,我想随机生成一个会话 ID,然后让该用户的所有相关数据仅与他们的实例有关。

我知道我需要来自this question 的密钥 我对文档的一般用法和other questions有了基本的了解 我知道最好远离这些类型的应用程序的全局变量from this question

我认为每个浏览器请求都会自动分离会话及其数据,但我一定遗漏了一些东西。我在这里发布了代码的主要部分。如果我的问题解释不清楚,您可以在youngblksocrates.pythonanywhere.com 通过与不同浏览器的机器人聊天来查看问题。非常感谢!

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'))

感谢您抽出宝贵时间,很抱歉这个冗长的问题!

【问题讨论】:

    标签: python session web-applications flask session-state


    【解决方案1】:

    我四处询问,发现如果文件的顶层有变量,那么它们将在每次请求时被覆盖

    由于数据存储在 currentProfilelearnBoutClass 变量中,我从顶层删除了这些变量,并用会话字典中的变量替换它们:session['profiledata']session['scriptdata']

    这解决了最初的问题。

    【讨论】:

    • 我认为您实际上的意思是顶级(模块级)变量将不会在每次请求时都被覆盖。这就是为什么两个浏览器都使用相同的 currentProfile,因此聊天会混淆。
    • 好吧,就像他们被任何客户的任何请求所覆盖,所以聊天是混在一起的,对吧?就像浏览器#1 currentProfile 将有信息“foo”,然后浏览器#2 会说一些东西,currentProfile 变成浏览器#1 和浏览器#2 的“bar”。因此,当浏览器 #1 提出一个新问题时,currentProfile 仍然是“bar”,这将使机器人以不同于用户预期的方式回答问题。
    • 也许我错误地使用了“请求”。我在 Web 开发方面的经验有限。似乎我们可能在说同样的话。说模块级变量在客户端之间共享是否更准确? @康拉德
    猜你喜欢
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    • 2018-09-26
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    • 2012-01-22
    相关资源
    最近更新 更多