2017-11-20 1 views
12

나는 Flask + gevent를 사용하고 있으며, greenlet의 목표 기능 내부에서 flask.g 응용 프로그램 전역에 액세스하려고합니다. 나는 copy_current_request_context 장식을 사용하고 문서에 주어진 예제와 매우 유사한 상황이있어 : 플라스크에 들어가기 greenlet

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

내가 새 응용 프로그램 컨텍스트가 생각 :

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' 

그러나, 나는 다음과 같은 오류를 요청 컨텍스트가 복사되면 푸시됩니까? 플라스크 코드 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.gas the doc says하지 요청 문맥에, bound 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 _ 

는 그러나, 나는 패스 데이터가 깨끗 인수를 통해 명시 적으로 greenlet하는 것을 선호합니다.