【问题标题】:Use a flask session inside a python thread在 python 线程中使用烧瓶会话
【发布时间】:2015-09-29 15:40:48
【问题描述】:

如何在 python 线程中更新烧瓶会话?以下代码抛出此错误:

*** RuntimeError: 在请求上下文之外工作

from flask import session
def test(ses):
    ses['test'] = "test"

@app.route('/test', methods=['POST', 'GET'])
def mytest():
    t = threading.Thread(target=test, args=(session, ))
    t.start()

【问题讨论】:

标签: python session flask


【解决方案1】:

我所见过的文档都没有真正详细说明为什么在这个框架中这是不可能的——就好像他们从未听说过这个用例一样。

简而言之,内置会话使用用户的浏览器(cookie)作为会话的存储 - 这不是我理解的会话,哦,天哪,安全问题 - 不要在那里存储任何秘密- 会话基本上是 JSON 编码,压缩然后设置为 cookie - 我猜至少它是签名的。

Flask-Session 通过表现得更像其他框架中的会话来缓解安全问题 - cookie 只是一个仅在后端有意义的不透明标识符 - 但每次会话更改时值都会更改,需要将 cookie 发送到再次浏览器 - 后台线程在很久以前完成时将无法访问请求,因此您所拥有的只是单向传输数据 - 离开会话并进入后台任务。

我可以建议行李提取模式吗?您的初始请求处理函数指定某个共享存储中的某个键 - 磁盘上的文件,数据库中由某个键标识的行,内存缓存中的对象键 - 无论如何 - 并将其放入会话中,然后通过会话到您的后台进程,该进程可以检查会话以查找放置结果的位置。然后,您的后续请求处理函数可以检查此位置以获取结果。

【讨论】:

    【解决方案2】:

    当您执行t.start() 时,您正在创建一个独立的执行线程,该线程与主线程的执行不同步。

    Flask session object只在context of a particular HTTP request中定义

    第二个线程(t)中的变量session意思是什么?

    t 执行时,不能保证来自主线程的用户请求仍然存在或处于可修改状态。可能 HTTP 请求已经在主线程中处理完毕。

    Flask 检测到您正在尝试操作依赖于特定上下文的对象,并且您的代码未在该上下文中运行。所以它引发了一个异常。

    有多种方法可以将来自多个线程的输出同步到单个请求上下文中,但是……您实际上想在这里做什么?

    【讨论】:

    • 就我而言,我想将函数“test”作为线程运行,因为它正在做很多事情并且需要很长时间才能执行,我不想等待它完成,所以我只运行将更新在会话变量中运行的进程状态的线程,我将从会话变量中检查(使用 ajax 调用)这些进程的状态。换句话说,这个想法是进行第一个 ajax 调用,只运行进程而不等待响应,并让下一个 ajax 调用检查状态。
    • 这当然是可能的,但是你需要一种机制来同步后台任务和主线程。我建议你看看 Miguel Grinberg 的烧瓶教程中的 background task with threads example
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-18
    • 1970-01-01
    • 1970-01-01
    • 2015-12-30
    相关资源
    最近更新 更多