librelist archives

« back to archive

[Help] Local Context

[Help] Local Context

From:
Indra Gunawan
Date:
2011-09-04 @ 15:08
Hi, newbie here. I need (a) local context object just like flask's g,
request, session etc.
Here I take from globals.py, adjusted to my need:

# myglobals.py
from functools import partial
from werkzeug import LocalStack, LocalProxy

def _lookup_object(name):
    top = _request_ctx_stack.top
    if top is None:
        raise RuntimeError('working outside of request context')
    return getattr(top, name)

# context locals
_request_ctx_stack = LocalStack()
script_manager = LocalProxy(partial(_lookup_object, 'script_manager'))

class ScriptManager(object):
   pass

------------------------------------

The question is, how I play with this (script_manager) in my request?

# mymodule.py
from myglobals import script_manager

# one or more function in another module uses global script_manager variable
def render_widget(abc):
    script_manager.append('yet another script')
    script_manager.append('blabla %s' % abc)

------------------------------------

# myview.py
from myglobals import script_manager, ScriptManager

# view module
@app.route('/mytask)
def mytask():
    render_widget(request.args.get('ch_id'))
    scripts = str(script_manager)
    return render_template('mytask.html', scripts=scripts)

When / where I create new instance of ScriptManager? How to set / release
script_manager local context?

Thank you very much

Re: [flask] [Help] Local Context

From:
Armin Ronacher
Date:
2011-09-04 @ 15:39
Hi,

On 9/4/11 5:08 PM, Indra Gunawan wrote:
> Hi, newbie here. I need (a) local context object just like flask's g,
> request, session etc.
Two ways.  The first one is the obvious one: don't create a second local
proxy but reuse the one that is there.  We explicitly made
_request_ctx_stack a public interface for the powerusers so you can
create more proxies with it.  For instance you can create a proxy to a
new object like this:

from flask import _request_ctx_stack
from werkzeug.local import LocalProxy
foo = LocalProxy(lambda: _request_ctx_stack.top.foo)

Note that you will still get attribute errors from this if you did not
set _request_ctx_stack at one point, so make sure to store something
there at the beginning of the request:

@app.before_request
def put_something_on_request_ctx_stack():
    _request_ctx_stack.top.foo = MyObject()

From that point onwards to the end of the request foo will be a proxy to
an instance of MyObject.

The second possibility is of course to create a local stack altogether.
 There however be dragons:

-  In a nutshell, Flask pushes and pops the request context with a
   context manager that is returned by Flask.request_context.  You
   could override that:

   class MyFlask(Flask):
       @contextmanager
       def request_context(self, environ):
           with Flask.request_context(self, environ) as c:
               my_own_stack.push()
               try:
                   yield c
               finally:
                   my_own_stack.pop()

-  The problem with that however is that you have to consider that
   Flask's own context manager can be kept alive for a longer time
   with the test utilities.  As such Flask will sometimes push and
   pop the _request_ctx_stack by hand and you will not be notified
   about that yourself.


Regards,
Armin

Re: [flask] [Help] Local Context

From:
Indra Gunawan
Date:
2011-09-04 @ 22:33
Thank you very much Armin, really help me.

Regards,
Indra Gunawan
On Sep 4, 2011 10:40 PM, "Armin Ronacher" <armin.ronacher@active-4.com>
wrote:
> Hi,
>
> On 9/4/11 5:08 PM, Indra Gunawan wrote:
>> Hi, newbie here. I need (a) local context object just like flask's g,
>> request, session etc.
> Two ways. The first one is the obvious one: don't create a second local
> proxy but reuse the one that is there. We explicitly made
> _request_ctx_stack a public interface for the powerusers so you can
> create more proxies with it. For instance you can create a proxy to a
> new object like this:
>
> from flask import _request_ctx_stack
> from werkzeug.local import LocalProxy
> foo = LocalProxy(lambda: _request_ctx_stack.top.foo)
>
> Note that you will still get attribute errors from this if you did not
> set _request_ctx_stack at one point, so make sure to store something
> there at the beginning of the request:
>
> @app.before_request
> def put_something_on_request_ctx_stack():
> _request_ctx_stack.top.foo = MyObject()
>
>>From that point onwards to the end of the request foo will be a proxy to
> an instance of MyObject.
>
> The second possibility is of course to create a local stack altogether.
> There however be dragons:
>
> - In a nutshell, Flask pushes and pops the request context with a
> context manager that is returned by Flask.request_context. You
> could override that:
>
> class MyFlask(Flask):
> @contextmanager
> def request_context(self, environ):
> with Flask.request_context(self, environ) as c:
> my_own_stack.push()
> try:
> yield c
> finally:
> my_own_stack.pop()
>
> - The problem with that however is that you have to consider that
> Flask's own context manager can be kept alive for a longer time
> with the test utilities. As such Flask will sometimes push and
> pop the _request_ctx_stack by hand and you will not be notified
> about that yourself.
>
>
> Regards,
> Armin