Access flask.g inside greenlet

二次信任 提交于 2019-12-10 01:12:12

问题


I'm using Flask + gevent and want to access the flask.g application global inside the target function of a greenlet. I'm using the copy_current_request_context decorator and have a situation pretty similar to example given in the docs:

import gevent
from flask import copy_current_request_context, g

@app.route('/')
def index():
    g.user_data = 'foobar'
    g.more_user_data = 'baz'

    @copy_current_request_context
    def do_some_work():
        some_func(g.user_data, g.more_user_data)
        ...  

    gevent.spawn(do_some_work)
    return 'Regular response'

However, I get the following error:

AttributeError: '_AppCtxGlobals' object has no attribute 'user_data'

I think a new application context is pushed when the request context is copied? I set a trace in the Flask code here and that seems to be the case. So the error isn't all that surprising because the flask.g object is application context scoped as of 0.10 (see http://flask.pocoo.org/docs/0.12/api/#flask.Flask.app_ctx_globals_class).

Obviously, I can just pass the user data into the target function as arguments:

import gevent
from flask import g

@app.route('/')
def index():
    g.user_data = 'foobar'
    g.more_user_data = 'baz'

    def do_some_work(user_data, more_user_data):
        some_func(user_data, more_user_data)
        ...  

    gevent.spawn(do_some_work, g.user_data, g.more_user_data)
    return 'Regular response'

And this works just fine, but I was hoping to use flask.g if possible.


回答1:


flask.g is bound with the app context, not on request context, as the doc says:

Starting with Flask 0.10 this is stored on the application context and no longer on the request context ...

copy_current_request_context() only copy request context, but give you a new app context. You could create one to pass current app context with closure:

def copy_current_app_context(f):
    from flask.globals import _app_ctx_stack
    appctx = _app_ctx_stack.top
    def _(*args, **kwargs):
        with appctx:
            return f(*args, **kwargs)
    return _

However, I prefer pass data to greenlet explicitly via arguments, which is cleaner.



来源:https://stackoverflow.com/questions/47384600/access-flask-g-inside-greenlet

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!