When should Flask.g be used?












132















I saw that g will move from the request context to the app context in Flask 0.10, which made me confused about the intended use of g.



My understanding (for Flask 0.9) is that:





  • g lives in the request context, i.e., created afresh when the requests starts, and available until it ends


  • g is intended to be used as a "request blackboard", where I can put stuff relevant for the duration of the request (i.e., set a flag at the beginning of the request and handle it at the end, possibly from a before_request/after_request pair)

  • in addition to holding request-level-state, g can and should be used for resource management, i.e., holding database connections, etc.


Which of these sentences are no longer true in Flask 0.10? Can someone point me to a resource discussing the reasons for the change? What should I use as a "request blackboard" in Flask 0.10 - should I create my own app/extension specific thread-local proxy and push it to the context stack before_request? What's the point of resource management at the application context, if my application lives for a long while (not like a request) and thus the resources are never freed?










share|improve this question























  • I agree, that is a pretty odd change. Hopefully mitsuhiko implements some kind of request context object to replace g in 0.10, else it sounds like a lot of code might start developing some devious bugs.

    – Anorov
    Feb 26 '13 at 8:15






  • 7





    FWIW, Armin Ronacher (author of Flask) has released a sequel of "Advanced Flask Patterns" which shows some example code on how to use the new flask.g. speakerdeck.com/mitsuhiko/advanced-flask-patterns-1

    – Markus Unterwaditzer
    Feb 26 '13 at 22:24






  • 1





    also a new request context implies a new app context, so it should just work fine in normal use

    – Ronny
    Feb 26 '13 at 23:09
















132















I saw that g will move from the request context to the app context in Flask 0.10, which made me confused about the intended use of g.



My understanding (for Flask 0.9) is that:





  • g lives in the request context, i.e., created afresh when the requests starts, and available until it ends


  • g is intended to be used as a "request blackboard", where I can put stuff relevant for the duration of the request (i.e., set a flag at the beginning of the request and handle it at the end, possibly from a before_request/after_request pair)

  • in addition to holding request-level-state, g can and should be used for resource management, i.e., holding database connections, etc.


Which of these sentences are no longer true in Flask 0.10? Can someone point me to a resource discussing the reasons for the change? What should I use as a "request blackboard" in Flask 0.10 - should I create my own app/extension specific thread-local proxy and push it to the context stack before_request? What's the point of resource management at the application context, if my application lives for a long while (not like a request) and thus the resources are never freed?










share|improve this question























  • I agree, that is a pretty odd change. Hopefully mitsuhiko implements some kind of request context object to replace g in 0.10, else it sounds like a lot of code might start developing some devious bugs.

    – Anorov
    Feb 26 '13 at 8:15






  • 7





    FWIW, Armin Ronacher (author of Flask) has released a sequel of "Advanced Flask Patterns" which shows some example code on how to use the new flask.g. speakerdeck.com/mitsuhiko/advanced-flask-patterns-1

    – Markus Unterwaditzer
    Feb 26 '13 at 22:24






  • 1





    also a new request context implies a new app context, so it should just work fine in normal use

    – Ronny
    Feb 26 '13 at 23:09














132












132








132


51






I saw that g will move from the request context to the app context in Flask 0.10, which made me confused about the intended use of g.



My understanding (for Flask 0.9) is that:





  • g lives in the request context, i.e., created afresh when the requests starts, and available until it ends


  • g is intended to be used as a "request blackboard", where I can put stuff relevant for the duration of the request (i.e., set a flag at the beginning of the request and handle it at the end, possibly from a before_request/after_request pair)

  • in addition to holding request-level-state, g can and should be used for resource management, i.e., holding database connections, etc.


Which of these sentences are no longer true in Flask 0.10? Can someone point me to a resource discussing the reasons for the change? What should I use as a "request blackboard" in Flask 0.10 - should I create my own app/extension specific thread-local proxy and push it to the context stack before_request? What's the point of resource management at the application context, if my application lives for a long while (not like a request) and thus the resources are never freed?










share|improve this question














I saw that g will move from the request context to the app context in Flask 0.10, which made me confused about the intended use of g.



My understanding (for Flask 0.9) is that:





  • g lives in the request context, i.e., created afresh when the requests starts, and available until it ends


  • g is intended to be used as a "request blackboard", where I can put stuff relevant for the duration of the request (i.e., set a flag at the beginning of the request and handle it at the end, possibly from a before_request/after_request pair)

  • in addition to holding request-level-state, g can and should be used for resource management, i.e., holding database connections, etc.


Which of these sentences are no longer true in Flask 0.10? Can someone point me to a resource discussing the reasons for the change? What should I use as a "request blackboard" in Flask 0.10 - should I create my own app/extension specific thread-local proxy and push it to the context stack before_request? What's the point of resource management at the application context, if my application lives for a long while (not like a request) and thus the resources are never freed?







python flask






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Feb 26 '13 at 7:49









Yaniv AkninYaniv Aknin

1,71231622




1,71231622













  • I agree, that is a pretty odd change. Hopefully mitsuhiko implements some kind of request context object to replace g in 0.10, else it sounds like a lot of code might start developing some devious bugs.

    – Anorov
    Feb 26 '13 at 8:15






  • 7





    FWIW, Armin Ronacher (author of Flask) has released a sequel of "Advanced Flask Patterns" which shows some example code on how to use the new flask.g. speakerdeck.com/mitsuhiko/advanced-flask-patterns-1

    – Markus Unterwaditzer
    Feb 26 '13 at 22:24






  • 1





    also a new request context implies a new app context, so it should just work fine in normal use

    – Ronny
    Feb 26 '13 at 23:09



















  • I agree, that is a pretty odd change. Hopefully mitsuhiko implements some kind of request context object to replace g in 0.10, else it sounds like a lot of code might start developing some devious bugs.

    – Anorov
    Feb 26 '13 at 8:15






  • 7





    FWIW, Armin Ronacher (author of Flask) has released a sequel of "Advanced Flask Patterns" which shows some example code on how to use the new flask.g. speakerdeck.com/mitsuhiko/advanced-flask-patterns-1

    – Markus Unterwaditzer
    Feb 26 '13 at 22:24






  • 1





    also a new request context implies a new app context, so it should just work fine in normal use

    – Ronny
    Feb 26 '13 at 23:09

















I agree, that is a pretty odd change. Hopefully mitsuhiko implements some kind of request context object to replace g in 0.10, else it sounds like a lot of code might start developing some devious bugs.

– Anorov
Feb 26 '13 at 8:15





I agree, that is a pretty odd change. Hopefully mitsuhiko implements some kind of request context object to replace g in 0.10, else it sounds like a lot of code might start developing some devious bugs.

– Anorov
Feb 26 '13 at 8:15




7




7





FWIW, Armin Ronacher (author of Flask) has released a sequel of "Advanced Flask Patterns" which shows some example code on how to use the new flask.g. speakerdeck.com/mitsuhiko/advanced-flask-patterns-1

– Markus Unterwaditzer
Feb 26 '13 at 22:24





FWIW, Armin Ronacher (author of Flask) has released a sequel of "Advanced Flask Patterns" which shows some example code on how to use the new flask.g. speakerdeck.com/mitsuhiko/advanced-flask-patterns-1

– Markus Unterwaditzer
Feb 26 '13 at 22:24




1




1





also a new request context implies a new app context, so it should just work fine in normal use

– Ronny
Feb 26 '13 at 23:09





also a new request context implies a new app context, so it should just work fine in normal use

– Ronny
Feb 26 '13 at 23:09












2 Answers
2






active

oldest

votes


















89














Advanced Flask Patterns, as linked by Markus, explains some of the changes to g in 0.10:





  • g now lives in the application context.


  • Every request pushes a new application context, wiping the old one, so g can still be used to set flags per-request without change to code.

  • The application context is popped after teardown_request is called. (Armin's presentation explains this is because things like creating DB connections are tasks which setup the environment for the request, and should not be handled inside before_request and after_request)






share|improve this answer


























  • In the source code you linked to, when app_ctx is None or app_ctx.app != self.app is False, the old application context seems to be reused? This doesn't seem to be right, since the application context "will not be shared between requests"...

    – nalzok
    Jul 18 '17 at 8:33






  • 1





    Are you referring to the pushing of app.app_context()? If so, it should be noted app_context() instantiates a new application context every call — it never reuses a context.

    – theY4Kman
    Jul 18 '17 at 19:20








  • 1





    Yes that's true, but when app_ctx is not None and app_ctx.app == self.app, the app_ctx = self.app.app_context() line is not executed; only self._implicit_app_ctx_stack.append(None) is executed in this case.

    – nalzok
    Jul 19 '17 at 4:45






  • 1





    Oh, sorry, I misread! In a production setting, there is only one request served per thread (or greenlet). Only one RequestContext is pushed, so only one AppContext is pushed. But if debug mode is on and a request fails, Flask saves the context, so it can be used with the debugger. None is appended to the _app_ctx_stack, so when the request is being torn down, it knows not to pop the AppContext just yet. The same thing occurs with the test client, which retains the context, so it can be inspected.

    – theY4Kman
    Jul 29 '17 at 21:04



















49














As an addendum to the information in this thread: I've been a bit confused by the behavior of flask.g too, but some quick testing has helped me to clarify it. Here's what I tried out:



from flask import Flask, g
app = Flask(__name__)

with app.app_context():
print('in app context, before first request context')
print('setting g.foo to abc')
g.foo = 'abc'
print('g.foo should be abc, is: {0}'.format(g.foo))

with app.test_request_context():
print('in first request context')
print('g.foo should be abc, is: {0}'.format(g.foo))
print('setting g.foo to xyz')
g.foo = 'xyz'
print('g.foo should be xyz, is: {0}'.format(g.foo))

print('in app context, after first request context')
print('g.foo should be abc, is: {0}'.format(g.foo))

with app.test_request_context():
print('in second request context')
print('g.foo should be abc, is: {0}'.format(g.foo))
print('setting g.foo to pqr')
g.foo = 'pqr'
print('g.foo should be pqr, is: {0}'.format(g.foo))

print('in app context, after second request context')
print('g.foo should be abc, is: {0}'.format(g.foo))


And here's the output that it gives:



in app context, before first request context
setting g.foo to abc
g.foo should be abc, is: abc
in first request context
g.foo should be abc, is: abc
setting g.foo to xyz
g.foo should be xyz, is: xyz
in app context, after first request context
g.foo should be abc, is: xyz
in second request context
g.foo should be abc, is: xyz
setting g.foo to pqr
g.foo should be pqr, is: pqr
in app context, after second request context
g.foo should be abc, is: pqr


As theY4Kman said above, "Every request pushes a new application context". And as the Flask docs say, the application context "will not be shared between requests". Now, what hasn't been explicitly stated (although I guess it's implied from these statements), and what my testing clearly shows, is that you should never explicitly create multiple request contexts nested inside one application context, because flask.g (and co) doesn't have any magic whereby it functions in the two different "levels" of context, with different states existing independently at the application and request levels.



The reality is that "application context" is potentially quite a misleading name, because app.app_context() is a per-request context, exactly the same as the "request context". Think of it as a "request context lite", only required in the case where you need some of the variables that normally require a request context, but you don't need access to any request object (e.g. when running batch DB operations in a shell script). If you try and extend the application context to encompass more than one request context, you're asking for trouble. So, rather than my test above, you should instead write code like this with Flask's contexts:



from flask import Flask, g
app = Flask(__name__)

with app.app_context():
print('in app context, before first request context')
print('setting g.foo to abc')
g.foo = 'abc'
print('g.foo should be abc, is: {0}'.format(g.foo))

with app.test_request_context():
print('in first request context')
print('g.foo should be None, is: {0}'.format(g.get('foo')))
print('setting g.foo to xyz')
g.foo = 'xyz'
print('g.foo should be xyz, is: {0}'.format(g.foo))

with app.test_request_context():
print('in second request context')
print('g.foo should be None, is: {0}'.format(g.get('foo')))
print('setting g.foo to pqr')
g.foo = 'pqr'
print('g.foo should be pqr, is: {0}'.format(g.foo))


Which will give the expected results:



in app context, before first request context
setting g.foo to abc
g.foo should be abc, is: abc
in first request context
g.foo should be None, is: None
setting g.foo to xyz
g.foo should be xyz, is: xyz
in second request context
g.foo should be None, is: None
setting g.foo to pqr
g.foo should be pqr, is: pqr





share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f15083967%2fwhen-should-flask-g-be-used%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    89














    Advanced Flask Patterns, as linked by Markus, explains some of the changes to g in 0.10:





    • g now lives in the application context.


    • Every request pushes a new application context, wiping the old one, so g can still be used to set flags per-request without change to code.

    • The application context is popped after teardown_request is called. (Armin's presentation explains this is because things like creating DB connections are tasks which setup the environment for the request, and should not be handled inside before_request and after_request)






    share|improve this answer


























    • In the source code you linked to, when app_ctx is None or app_ctx.app != self.app is False, the old application context seems to be reused? This doesn't seem to be right, since the application context "will not be shared between requests"...

      – nalzok
      Jul 18 '17 at 8:33






    • 1





      Are you referring to the pushing of app.app_context()? If so, it should be noted app_context() instantiates a new application context every call — it never reuses a context.

      – theY4Kman
      Jul 18 '17 at 19:20








    • 1





      Yes that's true, but when app_ctx is not None and app_ctx.app == self.app, the app_ctx = self.app.app_context() line is not executed; only self._implicit_app_ctx_stack.append(None) is executed in this case.

      – nalzok
      Jul 19 '17 at 4:45






    • 1





      Oh, sorry, I misread! In a production setting, there is only one request served per thread (or greenlet). Only one RequestContext is pushed, so only one AppContext is pushed. But if debug mode is on and a request fails, Flask saves the context, so it can be used with the debugger. None is appended to the _app_ctx_stack, so when the request is being torn down, it knows not to pop the AppContext just yet. The same thing occurs with the test client, which retains the context, so it can be inspected.

      – theY4Kman
      Jul 29 '17 at 21:04
















    89














    Advanced Flask Patterns, as linked by Markus, explains some of the changes to g in 0.10:





    • g now lives in the application context.


    • Every request pushes a new application context, wiping the old one, so g can still be used to set flags per-request without change to code.

    • The application context is popped after teardown_request is called. (Armin's presentation explains this is because things like creating DB connections are tasks which setup the environment for the request, and should not be handled inside before_request and after_request)






    share|improve this answer


























    • In the source code you linked to, when app_ctx is None or app_ctx.app != self.app is False, the old application context seems to be reused? This doesn't seem to be right, since the application context "will not be shared between requests"...

      – nalzok
      Jul 18 '17 at 8:33






    • 1





      Are you referring to the pushing of app.app_context()? If so, it should be noted app_context() instantiates a new application context every call — it never reuses a context.

      – theY4Kman
      Jul 18 '17 at 19:20








    • 1





      Yes that's true, but when app_ctx is not None and app_ctx.app == self.app, the app_ctx = self.app.app_context() line is not executed; only self._implicit_app_ctx_stack.append(None) is executed in this case.

      – nalzok
      Jul 19 '17 at 4:45






    • 1





      Oh, sorry, I misread! In a production setting, there is only one request served per thread (or greenlet). Only one RequestContext is pushed, so only one AppContext is pushed. But if debug mode is on and a request fails, Flask saves the context, so it can be used with the debugger. None is appended to the _app_ctx_stack, so when the request is being torn down, it knows not to pop the AppContext just yet. The same thing occurs with the test client, which retains the context, so it can be inspected.

      – theY4Kman
      Jul 29 '17 at 21:04














    89












    89








    89







    Advanced Flask Patterns, as linked by Markus, explains some of the changes to g in 0.10:





    • g now lives in the application context.


    • Every request pushes a new application context, wiping the old one, so g can still be used to set flags per-request without change to code.

    • The application context is popped after teardown_request is called. (Armin's presentation explains this is because things like creating DB connections are tasks which setup the environment for the request, and should not be handled inside before_request and after_request)






    share|improve this answer















    Advanced Flask Patterns, as linked by Markus, explains some of the changes to g in 0.10:





    • g now lives in the application context.


    • Every request pushes a new application context, wiping the old one, so g can still be used to set flags per-request without change to code.

    • The application context is popped after teardown_request is called. (Armin's presentation explains this is because things like creating DB connections are tasks which setup the environment for the request, and should not be handled inside before_request and after_request)







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Aug 17 '18 at 2:21

























    answered Feb 26 '13 at 23:06









    theY4KmantheY4Kman

    1,8431515




    1,8431515













    • In the source code you linked to, when app_ctx is None or app_ctx.app != self.app is False, the old application context seems to be reused? This doesn't seem to be right, since the application context "will not be shared between requests"...

      – nalzok
      Jul 18 '17 at 8:33






    • 1





      Are you referring to the pushing of app.app_context()? If so, it should be noted app_context() instantiates a new application context every call — it never reuses a context.

      – theY4Kman
      Jul 18 '17 at 19:20








    • 1





      Yes that's true, but when app_ctx is not None and app_ctx.app == self.app, the app_ctx = self.app.app_context() line is not executed; only self._implicit_app_ctx_stack.append(None) is executed in this case.

      – nalzok
      Jul 19 '17 at 4:45






    • 1





      Oh, sorry, I misread! In a production setting, there is only one request served per thread (or greenlet). Only one RequestContext is pushed, so only one AppContext is pushed. But if debug mode is on and a request fails, Flask saves the context, so it can be used with the debugger. None is appended to the _app_ctx_stack, so when the request is being torn down, it knows not to pop the AppContext just yet. The same thing occurs with the test client, which retains the context, so it can be inspected.

      – theY4Kman
      Jul 29 '17 at 21:04



















    • In the source code you linked to, when app_ctx is None or app_ctx.app != self.app is False, the old application context seems to be reused? This doesn't seem to be right, since the application context "will not be shared between requests"...

      – nalzok
      Jul 18 '17 at 8:33






    • 1





      Are you referring to the pushing of app.app_context()? If so, it should be noted app_context() instantiates a new application context every call — it never reuses a context.

      – theY4Kman
      Jul 18 '17 at 19:20








    • 1





      Yes that's true, but when app_ctx is not None and app_ctx.app == self.app, the app_ctx = self.app.app_context() line is not executed; only self._implicit_app_ctx_stack.append(None) is executed in this case.

      – nalzok
      Jul 19 '17 at 4:45






    • 1





      Oh, sorry, I misread! In a production setting, there is only one request served per thread (or greenlet). Only one RequestContext is pushed, so only one AppContext is pushed. But if debug mode is on and a request fails, Flask saves the context, so it can be used with the debugger. None is appended to the _app_ctx_stack, so when the request is being torn down, it knows not to pop the AppContext just yet. The same thing occurs with the test client, which retains the context, so it can be inspected.

      – theY4Kman
      Jul 29 '17 at 21:04

















    In the source code you linked to, when app_ctx is None or app_ctx.app != self.app is False, the old application context seems to be reused? This doesn't seem to be right, since the application context "will not be shared between requests"...

    – nalzok
    Jul 18 '17 at 8:33





    In the source code you linked to, when app_ctx is None or app_ctx.app != self.app is False, the old application context seems to be reused? This doesn't seem to be right, since the application context "will not be shared between requests"...

    – nalzok
    Jul 18 '17 at 8:33




    1




    1





    Are you referring to the pushing of app.app_context()? If so, it should be noted app_context() instantiates a new application context every call — it never reuses a context.

    – theY4Kman
    Jul 18 '17 at 19:20







    Are you referring to the pushing of app.app_context()? If so, it should be noted app_context() instantiates a new application context every call — it never reuses a context.

    – theY4Kman
    Jul 18 '17 at 19:20






    1




    1





    Yes that's true, but when app_ctx is not None and app_ctx.app == self.app, the app_ctx = self.app.app_context() line is not executed; only self._implicit_app_ctx_stack.append(None) is executed in this case.

    – nalzok
    Jul 19 '17 at 4:45





    Yes that's true, but when app_ctx is not None and app_ctx.app == self.app, the app_ctx = self.app.app_context() line is not executed; only self._implicit_app_ctx_stack.append(None) is executed in this case.

    – nalzok
    Jul 19 '17 at 4:45




    1




    1





    Oh, sorry, I misread! In a production setting, there is only one request served per thread (or greenlet). Only one RequestContext is pushed, so only one AppContext is pushed. But if debug mode is on and a request fails, Flask saves the context, so it can be used with the debugger. None is appended to the _app_ctx_stack, so when the request is being torn down, it knows not to pop the AppContext just yet. The same thing occurs with the test client, which retains the context, so it can be inspected.

    – theY4Kman
    Jul 29 '17 at 21:04





    Oh, sorry, I misread! In a production setting, there is only one request served per thread (or greenlet). Only one RequestContext is pushed, so only one AppContext is pushed. But if debug mode is on and a request fails, Flask saves the context, so it can be used with the debugger. None is appended to the _app_ctx_stack, so when the request is being torn down, it knows not to pop the AppContext just yet. The same thing occurs with the test client, which retains the context, so it can be inspected.

    – theY4Kman
    Jul 29 '17 at 21:04













    49














    As an addendum to the information in this thread: I've been a bit confused by the behavior of flask.g too, but some quick testing has helped me to clarify it. Here's what I tried out:



    from flask import Flask, g
    app = Flask(__name__)

    with app.app_context():
    print('in app context, before first request context')
    print('setting g.foo to abc')
    g.foo = 'abc'
    print('g.foo should be abc, is: {0}'.format(g.foo))

    with app.test_request_context():
    print('in first request context')
    print('g.foo should be abc, is: {0}'.format(g.foo))
    print('setting g.foo to xyz')
    g.foo = 'xyz'
    print('g.foo should be xyz, is: {0}'.format(g.foo))

    print('in app context, after first request context')
    print('g.foo should be abc, is: {0}'.format(g.foo))

    with app.test_request_context():
    print('in second request context')
    print('g.foo should be abc, is: {0}'.format(g.foo))
    print('setting g.foo to pqr')
    g.foo = 'pqr'
    print('g.foo should be pqr, is: {0}'.format(g.foo))

    print('in app context, after second request context')
    print('g.foo should be abc, is: {0}'.format(g.foo))


    And here's the output that it gives:



    in app context, before first request context
    setting g.foo to abc
    g.foo should be abc, is: abc
    in first request context
    g.foo should be abc, is: abc
    setting g.foo to xyz
    g.foo should be xyz, is: xyz
    in app context, after first request context
    g.foo should be abc, is: xyz
    in second request context
    g.foo should be abc, is: xyz
    setting g.foo to pqr
    g.foo should be pqr, is: pqr
    in app context, after second request context
    g.foo should be abc, is: pqr


    As theY4Kman said above, "Every request pushes a new application context". And as the Flask docs say, the application context "will not be shared between requests". Now, what hasn't been explicitly stated (although I guess it's implied from these statements), and what my testing clearly shows, is that you should never explicitly create multiple request contexts nested inside one application context, because flask.g (and co) doesn't have any magic whereby it functions in the two different "levels" of context, with different states existing independently at the application and request levels.



    The reality is that "application context" is potentially quite a misleading name, because app.app_context() is a per-request context, exactly the same as the "request context". Think of it as a "request context lite", only required in the case where you need some of the variables that normally require a request context, but you don't need access to any request object (e.g. when running batch DB operations in a shell script). If you try and extend the application context to encompass more than one request context, you're asking for trouble. So, rather than my test above, you should instead write code like this with Flask's contexts:



    from flask import Flask, g
    app = Flask(__name__)

    with app.app_context():
    print('in app context, before first request context')
    print('setting g.foo to abc')
    g.foo = 'abc'
    print('g.foo should be abc, is: {0}'.format(g.foo))

    with app.test_request_context():
    print('in first request context')
    print('g.foo should be None, is: {0}'.format(g.get('foo')))
    print('setting g.foo to xyz')
    g.foo = 'xyz'
    print('g.foo should be xyz, is: {0}'.format(g.foo))

    with app.test_request_context():
    print('in second request context')
    print('g.foo should be None, is: {0}'.format(g.get('foo')))
    print('setting g.foo to pqr')
    g.foo = 'pqr'
    print('g.foo should be pqr, is: {0}'.format(g.foo))


    Which will give the expected results:



    in app context, before first request context
    setting g.foo to abc
    g.foo should be abc, is: abc
    in first request context
    g.foo should be None, is: None
    setting g.foo to xyz
    g.foo should be xyz, is: xyz
    in second request context
    g.foo should be None, is: None
    setting g.foo to pqr
    g.foo should be pqr, is: pqr





    share|improve this answer






























      49














      As an addendum to the information in this thread: I've been a bit confused by the behavior of flask.g too, but some quick testing has helped me to clarify it. Here's what I tried out:



      from flask import Flask, g
      app = Flask(__name__)

      with app.app_context():
      print('in app context, before first request context')
      print('setting g.foo to abc')
      g.foo = 'abc'
      print('g.foo should be abc, is: {0}'.format(g.foo))

      with app.test_request_context():
      print('in first request context')
      print('g.foo should be abc, is: {0}'.format(g.foo))
      print('setting g.foo to xyz')
      g.foo = 'xyz'
      print('g.foo should be xyz, is: {0}'.format(g.foo))

      print('in app context, after first request context')
      print('g.foo should be abc, is: {0}'.format(g.foo))

      with app.test_request_context():
      print('in second request context')
      print('g.foo should be abc, is: {0}'.format(g.foo))
      print('setting g.foo to pqr')
      g.foo = 'pqr'
      print('g.foo should be pqr, is: {0}'.format(g.foo))

      print('in app context, after second request context')
      print('g.foo should be abc, is: {0}'.format(g.foo))


      And here's the output that it gives:



      in app context, before first request context
      setting g.foo to abc
      g.foo should be abc, is: abc
      in first request context
      g.foo should be abc, is: abc
      setting g.foo to xyz
      g.foo should be xyz, is: xyz
      in app context, after first request context
      g.foo should be abc, is: xyz
      in second request context
      g.foo should be abc, is: xyz
      setting g.foo to pqr
      g.foo should be pqr, is: pqr
      in app context, after second request context
      g.foo should be abc, is: pqr


      As theY4Kman said above, "Every request pushes a new application context". And as the Flask docs say, the application context "will not be shared between requests". Now, what hasn't been explicitly stated (although I guess it's implied from these statements), and what my testing clearly shows, is that you should never explicitly create multiple request contexts nested inside one application context, because flask.g (and co) doesn't have any magic whereby it functions in the two different "levels" of context, with different states existing independently at the application and request levels.



      The reality is that "application context" is potentially quite a misleading name, because app.app_context() is a per-request context, exactly the same as the "request context". Think of it as a "request context lite", only required in the case where you need some of the variables that normally require a request context, but you don't need access to any request object (e.g. when running batch DB operations in a shell script). If you try and extend the application context to encompass more than one request context, you're asking for trouble. So, rather than my test above, you should instead write code like this with Flask's contexts:



      from flask import Flask, g
      app = Flask(__name__)

      with app.app_context():
      print('in app context, before first request context')
      print('setting g.foo to abc')
      g.foo = 'abc'
      print('g.foo should be abc, is: {0}'.format(g.foo))

      with app.test_request_context():
      print('in first request context')
      print('g.foo should be None, is: {0}'.format(g.get('foo')))
      print('setting g.foo to xyz')
      g.foo = 'xyz'
      print('g.foo should be xyz, is: {0}'.format(g.foo))

      with app.test_request_context():
      print('in second request context')
      print('g.foo should be None, is: {0}'.format(g.get('foo')))
      print('setting g.foo to pqr')
      g.foo = 'pqr'
      print('g.foo should be pqr, is: {0}'.format(g.foo))


      Which will give the expected results:



      in app context, before first request context
      setting g.foo to abc
      g.foo should be abc, is: abc
      in first request context
      g.foo should be None, is: None
      setting g.foo to xyz
      g.foo should be xyz, is: xyz
      in second request context
      g.foo should be None, is: None
      setting g.foo to pqr
      g.foo should be pqr, is: pqr





      share|improve this answer




























        49












        49








        49







        As an addendum to the information in this thread: I've been a bit confused by the behavior of flask.g too, but some quick testing has helped me to clarify it. Here's what I tried out:



        from flask import Flask, g
        app = Flask(__name__)

        with app.app_context():
        print('in app context, before first request context')
        print('setting g.foo to abc')
        g.foo = 'abc'
        print('g.foo should be abc, is: {0}'.format(g.foo))

        with app.test_request_context():
        print('in first request context')
        print('g.foo should be abc, is: {0}'.format(g.foo))
        print('setting g.foo to xyz')
        g.foo = 'xyz'
        print('g.foo should be xyz, is: {0}'.format(g.foo))

        print('in app context, after first request context')
        print('g.foo should be abc, is: {0}'.format(g.foo))

        with app.test_request_context():
        print('in second request context')
        print('g.foo should be abc, is: {0}'.format(g.foo))
        print('setting g.foo to pqr')
        g.foo = 'pqr'
        print('g.foo should be pqr, is: {0}'.format(g.foo))

        print('in app context, after second request context')
        print('g.foo should be abc, is: {0}'.format(g.foo))


        And here's the output that it gives:



        in app context, before first request context
        setting g.foo to abc
        g.foo should be abc, is: abc
        in first request context
        g.foo should be abc, is: abc
        setting g.foo to xyz
        g.foo should be xyz, is: xyz
        in app context, after first request context
        g.foo should be abc, is: xyz
        in second request context
        g.foo should be abc, is: xyz
        setting g.foo to pqr
        g.foo should be pqr, is: pqr
        in app context, after second request context
        g.foo should be abc, is: pqr


        As theY4Kman said above, "Every request pushes a new application context". And as the Flask docs say, the application context "will not be shared between requests". Now, what hasn't been explicitly stated (although I guess it's implied from these statements), and what my testing clearly shows, is that you should never explicitly create multiple request contexts nested inside one application context, because flask.g (and co) doesn't have any magic whereby it functions in the two different "levels" of context, with different states existing independently at the application and request levels.



        The reality is that "application context" is potentially quite a misleading name, because app.app_context() is a per-request context, exactly the same as the "request context". Think of it as a "request context lite", only required in the case where you need some of the variables that normally require a request context, but you don't need access to any request object (e.g. when running batch DB operations in a shell script). If you try and extend the application context to encompass more than one request context, you're asking for trouble. So, rather than my test above, you should instead write code like this with Flask's contexts:



        from flask import Flask, g
        app = Flask(__name__)

        with app.app_context():
        print('in app context, before first request context')
        print('setting g.foo to abc')
        g.foo = 'abc'
        print('g.foo should be abc, is: {0}'.format(g.foo))

        with app.test_request_context():
        print('in first request context')
        print('g.foo should be None, is: {0}'.format(g.get('foo')))
        print('setting g.foo to xyz')
        g.foo = 'xyz'
        print('g.foo should be xyz, is: {0}'.format(g.foo))

        with app.test_request_context():
        print('in second request context')
        print('g.foo should be None, is: {0}'.format(g.get('foo')))
        print('setting g.foo to pqr')
        g.foo = 'pqr'
        print('g.foo should be pqr, is: {0}'.format(g.foo))


        Which will give the expected results:



        in app context, before first request context
        setting g.foo to abc
        g.foo should be abc, is: abc
        in first request context
        g.foo should be None, is: None
        setting g.foo to xyz
        g.foo should be xyz, is: xyz
        in second request context
        g.foo should be None, is: None
        setting g.foo to pqr
        g.foo should be pqr, is: pqr





        share|improve this answer















        As an addendum to the information in this thread: I've been a bit confused by the behavior of flask.g too, but some quick testing has helped me to clarify it. Here's what I tried out:



        from flask import Flask, g
        app = Flask(__name__)

        with app.app_context():
        print('in app context, before first request context')
        print('setting g.foo to abc')
        g.foo = 'abc'
        print('g.foo should be abc, is: {0}'.format(g.foo))

        with app.test_request_context():
        print('in first request context')
        print('g.foo should be abc, is: {0}'.format(g.foo))
        print('setting g.foo to xyz')
        g.foo = 'xyz'
        print('g.foo should be xyz, is: {0}'.format(g.foo))

        print('in app context, after first request context')
        print('g.foo should be abc, is: {0}'.format(g.foo))

        with app.test_request_context():
        print('in second request context')
        print('g.foo should be abc, is: {0}'.format(g.foo))
        print('setting g.foo to pqr')
        g.foo = 'pqr'
        print('g.foo should be pqr, is: {0}'.format(g.foo))

        print('in app context, after second request context')
        print('g.foo should be abc, is: {0}'.format(g.foo))


        And here's the output that it gives:



        in app context, before first request context
        setting g.foo to abc
        g.foo should be abc, is: abc
        in first request context
        g.foo should be abc, is: abc
        setting g.foo to xyz
        g.foo should be xyz, is: xyz
        in app context, after first request context
        g.foo should be abc, is: xyz
        in second request context
        g.foo should be abc, is: xyz
        setting g.foo to pqr
        g.foo should be pqr, is: pqr
        in app context, after second request context
        g.foo should be abc, is: pqr


        As theY4Kman said above, "Every request pushes a new application context". And as the Flask docs say, the application context "will not be shared between requests". Now, what hasn't been explicitly stated (although I guess it's implied from these statements), and what my testing clearly shows, is that you should never explicitly create multiple request contexts nested inside one application context, because flask.g (and co) doesn't have any magic whereby it functions in the two different "levels" of context, with different states existing independently at the application and request levels.



        The reality is that "application context" is potentially quite a misleading name, because app.app_context() is a per-request context, exactly the same as the "request context". Think of it as a "request context lite", only required in the case where you need some of the variables that normally require a request context, but you don't need access to any request object (e.g. when running batch DB operations in a shell script). If you try and extend the application context to encompass more than one request context, you're asking for trouble. So, rather than my test above, you should instead write code like this with Flask's contexts:



        from flask import Flask, g
        app = Flask(__name__)

        with app.app_context():
        print('in app context, before first request context')
        print('setting g.foo to abc')
        g.foo = 'abc'
        print('g.foo should be abc, is: {0}'.format(g.foo))

        with app.test_request_context():
        print('in first request context')
        print('g.foo should be None, is: {0}'.format(g.get('foo')))
        print('setting g.foo to xyz')
        g.foo = 'xyz'
        print('g.foo should be xyz, is: {0}'.format(g.foo))

        with app.test_request_context():
        print('in second request context')
        print('g.foo should be None, is: {0}'.format(g.get('foo')))
        print('setting g.foo to pqr')
        g.foo = 'pqr'
        print('g.foo should be pqr, is: {0}'.format(g.foo))


        Which will give the expected results:



        in app context, before first request context
        setting g.foo to abc
        g.foo should be abc, is: abc
        in first request context
        g.foo should be None, is: None
        setting g.foo to xyz
        g.foo should be xyz, is: xyz
        in second request context
        g.foo should be None, is: None
        setting g.foo to pqr
        g.foo should be pqr, is: pqr






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 21 '18 at 19:48









        bluesmonk

        726217




        726217










        answered Oct 28 '15 at 4:17









        JazaJaza

        1,4011021




        1,4011021






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f15083967%2fwhen-should-flask-g-be-used%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Create new schema in PostgreSQL using DBeaver

            Deepest pit of an array with Javascript: test on Codility

            Costa Masnaga