2017-11-20 3 views
12

私はFlask + geventを使用しており、greenletのターゲット機能内でflask.gアプリケーショングローバルにアクセスしたいと考えています。 私はcopy_current_request_contextデコレータを使用してドキュメントに与えられた例とかなり似たような状況を持っている:アクセスフラスコgreenlet

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' 

しかし、私は次のエラーを取得:

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

を私は新しいアプリケーションコンテキストがあると思いますリクエストコンテキストがコピーされるとプッシュされますか?フラスココードhereでトレースを設定しましたが、そのように思われます。従って、flask.gオブジェクトは0.10からスコープされたアプリケーションコンテキストであるため、エラーはそれほど驚くべきものではありません(http://flask.pocoo.org/docs/0.12/api/#flask.Flask.app_ctx_globals_class参照)。

もちろん、私は、引数として、目標関数にユーザーデータを渡すことができます。

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' 

そして、これはうまく動作しますが、私は可能であればflask.gを使用することを期待していました。

+0

geventを使用している場合は、最初にインポートした直後にサルのパッチを適用しましたか? –

+0

そうですね、私はそれを私の例から除いたようです。しかし、はい、実際のコードで 'gevent.monkey'から' patch_all'を呼び出しています。 – jamesdarabi

+1

まず、 'flask.g'オブジェクトに' user_data'と 'more_user_data'を格納したいのですか?あなたがユーザーの賢明なデータ永続性を必要とするなら、 'flask.session'オブジェクトがあります。また、グローバルな永続性が必要な場合は、それらを格納するために 'module.attribute'を使用することができます。 –

答えて

6

flask.gは、ない要求コンテキストに、as the doc saysbound with the app context次のとおりです。

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

copy_current_request_context()のみ要求コンテキストをコピーしますが、あなたに新しいアプリのコンテキストを与えます。

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 _ 

しかし、私はデータを明示的に引数で明示的に渡すことをお勧めします。

関連する問題