CINXE.COM

The Request Context — Flask Documentation (3.1.x)

<!DOCTYPE html> <html lang="en" data-content_root="../"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>The Request Context &#8212; Flask Documentation (3.1.x)</title> <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=4f649999" /> <link rel="stylesheet" type="text/css" href="../_static/flask.css?v=b87c8d14" /> <script src="../_static/documentation_options.js?v=d71c4578"></script> <script src="../_static/doctools.js?v=9bcbadda"></script> <script src="../_static/sphinx_highlight.js?v=dc90522c"></script> <link rel="canonical" href="https://flask.palletsprojects.com/en/stable/reqcontext/" /> <link rel="icon" href="../_static/shortcut-icon.png"/> <link rel="index" title="Index" href="../genindex/" /> <link rel="search" title="Search" href="../search/" /> <link rel="next" title="Modular Applications with Blueprints" href="../blueprints/" /> <link rel="prev" title="The Application Context" href="../appcontext/" /> <script async type="text/javascript" src="/_/static/javascript/readthedocs-addons.js"></script><meta name="readthedocs-project-slug" content="flask" /><meta name="readthedocs-version-slug" content="stable" /><meta name="readthedocs-resolver-filename" content="/reqcontext/" /><meta name="readthedocs-http-status" content="200" /></head><body> <div class="related" role="navigation" aria-label="Related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../genindex/" title="General Index" accesskey="I">index</a></li> <li class="right" > <a href="../py-modindex/" title="Python Module Index" >modules</a> |</li> <li class="right" > <a href="../blueprints/" title="Modular Applications with Blueprints" accesskey="N">next</a> |</li> <li class="right" > <a href="../appcontext/" title="The Application Context" accesskey="P">previous</a> |</li> <li class="nav-item nav-item-0"><a href="../">Flask Documentation (3.1.x)</a> &#187;</li> <li class="nav-item nav-item-this"><a href="">The Request Context</a></li> </ul> </div> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body" role="main"> <section id="the-request-context"> <h1>The Request Context<a class="headerlink" href="#the-request-context" title="Link to this heading">露</a></h1> <p>The request context keeps track of the request-level data during a request. Rather than passing the request object to each function that runs during a request, the <a class="reference internal" href="../api/#flask.request" title="flask.request"><code class="xref py py-data docutils literal notranslate"><span class="pre">request</span></code></a> and <a class="reference internal" href="../api/#flask.session" title="flask.session"><code class="xref py py-data docutils literal notranslate"><span class="pre">session</span></code></a> proxies are accessed instead.</p> <p>This is similar to <a class="reference internal" href="../appcontext/"><span class="doc">The Application Context</span></a>, which keeps track of the application-level data independent of a request. A corresponding application context is pushed when a request context is pushed.</p> <section id="purpose-of-the-context"> <h2>Purpose of the Context<a class="headerlink" href="#purpose-of-the-context" title="Link to this heading">露</a></h2> <p>When the <a class="reference internal" href="../api/#flask.Flask" title="flask.Flask"><code class="xref py py-class docutils literal notranslate"><span class="pre">Flask</span></code></a> application handles a request, it creates a <a class="reference internal" href="../api/#flask.Request" title="flask.Request"><code class="xref py py-class docutils literal notranslate"><span class="pre">Request</span></code></a> object based on the environment it received from the WSGI server. Because a <em>worker</em> (thread, process, or coroutine depending on the server) handles only one request at a time, the request data can be considered global to that worker during that request. Flask uses the term <em>context local</em> for this.</p> <p>Flask automatically <em>pushes</em> a request context when handling a request. View functions, error handlers, and other functions that run during a request will have access to the <a class="reference internal" href="../api/#flask.request" title="flask.request"><code class="xref py py-data docutils literal notranslate"><span class="pre">request</span></code></a> proxy, which points to the request object for the current request.</p> </section> <section id="lifetime-of-the-context"> <h2>Lifetime of the Context<a class="headerlink" href="#lifetime-of-the-context" title="Link to this heading">露</a></h2> <p>When a Flask application begins handling a request, it pushes a request context, which also pushes an <a class="reference internal" href="../appcontext/"><span class="doc">app context</span></a>. When the request ends it pops the request context then the application context.</p> <p>The context is unique to each thread (or other worker type). <a class="reference internal" href="../api/#flask.request" title="flask.request"><code class="xref py py-data docutils literal notranslate"><span class="pre">request</span></code></a> cannot be passed to another thread, the other thread has a different context space and will not know about the request the parent thread was pointing to.</p> <p>Context locals are implemented using Python鈥檚 <a class="reference external" href="https://docs.python.org/3/library/contextvars.html#module-contextvars" title="(in Python v3.13)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">contextvars</span></code></a> and Werkzeug鈥檚 <a class="reference external" href="https://werkzeug.palletsprojects.com/en/stable/local/#werkzeug.local.LocalProxy" title="(in Werkzeug v3.1.x)"><code class="xref py py-class docutils literal notranslate"><span class="pre">LocalProxy</span></code></a>. Python manages the lifetime of context vars automatically, and local proxy wraps that low-level interface to make the data easier to work with.</p> </section> <section id="manually-push-a-context"> <h2>Manually Push a Context<a class="headerlink" href="#manually-push-a-context" title="Link to this heading">露</a></h2> <p>If you try to access <a class="reference internal" href="../api/#flask.request" title="flask.request"><code class="xref py py-data docutils literal notranslate"><span class="pre">request</span></code></a>, or anything that uses it, outside a request context, you鈥檒l get this error message:</p> <div class="highlight-pytb notranslate"><div class="highlight"><pre><span></span><span class="x">RuntimeError: Working outside of request context.</span> <span class="x">This typically means that you attempted to use functionality that</span> <span class="x">needed an active HTTP request. Consult the documentation on testing</span> <span class="x">for information about how to avoid this problem.</span> </pre></div> </div> <p>This should typically only happen when testing code that expects an active request. One option is to use the <a class="reference internal" href="../api/#flask.Flask.test_client" title="flask.Flask.test_client"><code class="xref py py-meth docutils literal notranslate"><span class="pre">test</span> <span class="pre">client</span></code></a> to simulate a full request. Or you can use <a class="reference internal" href="../api/#flask.Flask.test_request_context" title="flask.Flask.test_request_context"><code class="xref py py-meth docutils literal notranslate"><span class="pre">test_request_context()</span></code></a> in a <code class="docutils literal notranslate"><span class="pre">with</span></code> block, and everything that runs in the block will have access to <a class="reference internal" href="../api/#flask.request" title="flask.request"><code class="xref py py-data docutils literal notranslate"><span class="pre">request</span></code></a>, populated with your test data.</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">generate_report</span><span class="p">(</span><span class="n">year</span><span class="p">):</span> <span class="nb">format</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;format&quot;</span><span class="p">)</span> <span class="o">...</span> <span class="k">with</span> <span class="n">app</span><span class="o">.</span><span class="n">test_request_context</span><span class="p">(</span> <span class="s2">&quot;/make_report/2017&quot;</span><span class="p">,</span> <span class="n">query_string</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;format&quot;</span><span class="p">:</span> <span class="s2">&quot;short&quot;</span><span class="p">}</span> <span class="p">):</span> <span class="n">generate_report</span><span class="p">()</span> </pre></div> </div> <p>If you see that error somewhere else in your code not related to testing, it most likely indicates that you should move that code into a view function.</p> <p>For information on how to use the request context from the interactive Python shell, see <a class="reference internal" href="../shell/"><span class="doc">Working with the Shell</span></a>.</p> </section> <section id="how-the-context-works"> <h2>How the Context Works<a class="headerlink" href="#how-the-context-works" title="Link to this heading">露</a></h2> <p>The <a class="reference internal" href="../api/#flask.Flask.wsgi_app" title="flask.Flask.wsgi_app"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Flask.wsgi_app()</span></code></a> method is called to handle each request. It manages the contexts during the request. Internally, the request and application contexts work like stacks. When contexts are pushed, the proxies that depend on them are available and point at information from the top item.</p> <p>When the request starts, a <a class="reference internal" href="../api/#flask.ctx.RequestContext" title="flask.ctx.RequestContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">RequestContext</span></code></a> is created and pushed, which creates and pushes an <a class="reference internal" href="../api/#flask.ctx.AppContext" title="flask.ctx.AppContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">AppContext</span></code></a> first if a context for that application is not already the top context. While these contexts are pushed, the <a class="reference internal" href="../api/#flask.current_app" title="flask.current_app"><code class="xref py py-data docutils literal notranslate"><span class="pre">current_app</span></code></a>, <a class="reference internal" href="../api/#flask.g" title="flask.g"><code class="xref py py-data docutils literal notranslate"><span class="pre">g</span></code></a>, <a class="reference internal" href="../api/#flask.request" title="flask.request"><code class="xref py py-data docutils literal notranslate"><span class="pre">request</span></code></a>, and <a class="reference internal" href="../api/#flask.session" title="flask.session"><code class="xref py py-data docutils literal notranslate"><span class="pre">session</span></code></a> proxies are available to the original thread handling the request.</p> <p>Other contexts may be pushed to change the proxies during a request. While this is not a common pattern, it can be used in advanced applications to, for example, do internal redirects or chain different applications together.</p> <p>After the request is dispatched and a response is generated and sent, the request context is popped, which then pops the application context. Immediately before they are popped, the <a class="reference internal" href="../api/#flask.Flask.teardown_request" title="flask.Flask.teardown_request"><code class="xref py py-meth docutils literal notranslate"><span class="pre">teardown_request()</span></code></a> and <a class="reference internal" href="../api/#flask.Flask.teardown_appcontext" title="flask.Flask.teardown_appcontext"><code class="xref py py-meth docutils literal notranslate"><span class="pre">teardown_appcontext()</span></code></a> functions are executed. These execute even if an unhandled exception occurred during dispatch.</p> </section> <section id="callbacks-and-errors"> <span id="id1"></span><h2>Callbacks and Errors<a class="headerlink" href="#callbacks-and-errors" title="Link to this heading">露</a></h2> <p>Flask dispatches a request in multiple stages which can affect the request, response, and how errors are handled. The contexts are active during all of these stages.</p> <p>A <a class="reference internal" href="../api/#flask.Blueprint" title="flask.Blueprint"><code class="xref py py-class docutils literal notranslate"><span class="pre">Blueprint</span></code></a> can add handlers for these events that are specific to the blueprint. The handlers for a blueprint will run if the blueprint owns the route that matches the request.</p> <ol class="arabic simple"> <li><p>Before each request, <a class="reference internal" href="../api/#flask.Flask.before_request" title="flask.Flask.before_request"><code class="xref py py-meth docutils literal notranslate"><span class="pre">before_request()</span></code></a> functions are called. If one of these functions return a value, the other functions are skipped. The return value is treated as the response and the view function is not called.</p></li> <li><p>If the <a class="reference internal" href="../api/#flask.Flask.before_request" title="flask.Flask.before_request"><code class="xref py py-meth docutils literal notranslate"><span class="pre">before_request()</span></code></a> functions did not return a response, the view function for the matched route is called and returns a response.</p></li> <li><p>The return value of the view is converted into an actual response object and passed to the <a class="reference internal" href="../api/#flask.Flask.after_request" title="flask.Flask.after_request"><code class="xref py py-meth docutils literal notranslate"><span class="pre">after_request()</span></code></a> functions. Each function returns a modified or new response object.</p></li> <li><p>After the response is returned, the contexts are popped, which calls the <a class="reference internal" href="../api/#flask.Flask.teardown_request" title="flask.Flask.teardown_request"><code class="xref py py-meth docutils literal notranslate"><span class="pre">teardown_request()</span></code></a> and <a class="reference internal" href="../api/#flask.Flask.teardown_appcontext" title="flask.Flask.teardown_appcontext"><code class="xref py py-meth docutils literal notranslate"><span class="pre">teardown_appcontext()</span></code></a> functions. These functions are called even if an unhandled exception was raised at any point above.</p></li> </ol> <p>If an exception is raised before the teardown functions, Flask tries to match it with an <a class="reference internal" href="../api/#flask.Flask.errorhandler" title="flask.Flask.errorhandler"><code class="xref py py-meth docutils literal notranslate"><span class="pre">errorhandler()</span></code></a> function to handle the exception and return a response. If no error handler is found, or the handler itself raises an exception, Flask returns a generic <code class="docutils literal notranslate"><span class="pre">500</span> <span class="pre">Internal</span> <span class="pre">Server</span> <span class="pre">Error</span></code> response. The teardown functions are still called, and are passed the exception object.</p> <p>If debug mode is enabled, unhandled exceptions are not converted to a <code class="docutils literal notranslate"><span class="pre">500</span></code> response and instead are propagated to the WSGI server. This allows the development server to present the interactive debugger with the traceback.</p> <section id="teardown-callbacks"> <h3>Teardown Callbacks<a class="headerlink" href="#teardown-callbacks" title="Link to this heading">露</a></h3> <p>The teardown callbacks are independent of the request dispatch, and are instead called by the contexts when they are popped. The functions are called even if there is an unhandled exception during dispatch, and for manually pushed contexts. This means there is no guarantee that any other parts of the request dispatch have run first. Be sure to write these functions in a way that does not depend on other callbacks and will not fail.</p> <p>During testing, it can be useful to defer popping the contexts after the request ends, so that their data can be accessed in the test function. Use the <a class="reference internal" href="../api/#flask.Flask.test_client" title="flask.Flask.test_client"><code class="xref py py-meth docutils literal notranslate"><span class="pre">test_client()</span></code></a> as a <code class="docutils literal notranslate"><span class="pre">with</span></code> block to preserve the contexts until the <code class="docutils literal notranslate"><span class="pre">with</span></code> block exits.</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span><span class="p">,</span> <span class="n">request</span> <span class="n">app</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span> <span class="nd">@app</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)</span> <span class="k">def</span> <span class="nf">hello</span><span class="p">():</span> <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;during view&#39;</span><span class="p">)</span> <span class="k">return</span> <span class="s1">&#39;Hello, World!&#39;</span> <span class="nd">@app</span><span class="o">.</span><span class="n">teardown_request</span> <span class="k">def</span> <span class="nf">show_teardown</span><span class="p">(</span><span class="n">exception</span><span class="p">):</span> <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;after with block&#39;</span><span class="p">)</span> <span class="k">with</span> <span class="n">app</span><span class="o">.</span><span class="n">test_request_context</span><span class="p">():</span> <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;during with block&#39;</span><span class="p">)</span> <span class="c1"># teardown functions are called after the context with block exits</span> <span class="k">with</span> <span class="n">app</span><span class="o">.</span><span class="n">test_client</span><span class="p">()</span> <span class="k">as</span> <span class="n">client</span><span class="p">:</span> <span class="n">client</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)</span> <span class="c1"># the contexts are not popped even though the request ended</span> <span class="nb">print</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">path</span><span class="p">)</span> <span class="c1"># the contexts are popped and teardown functions are called after</span> <span class="c1"># the client with block exits</span> </pre></div> </div> </section> <section id="signals"> <h3>Signals<a class="headerlink" href="#signals" title="Link to this heading">露</a></h3> <p>The following signals are sent:</p> <ol class="arabic simple"> <li><p><a class="reference internal" href="../api/#flask.request_started" title="flask.request_started"><code class="xref py py-data docutils literal notranslate"><span class="pre">request_started</span></code></a> is sent before the <a class="reference internal" href="../api/#flask.Flask.before_request" title="flask.Flask.before_request"><code class="xref py py-meth docutils literal notranslate"><span class="pre">before_request()</span></code></a> functions are called.</p></li> <li><p><a class="reference internal" href="../api/#flask.request_finished" title="flask.request_finished"><code class="xref py py-data docutils literal notranslate"><span class="pre">request_finished</span></code></a> is sent after the <a class="reference internal" href="../api/#flask.Flask.after_request" title="flask.Flask.after_request"><code class="xref py py-meth docutils literal notranslate"><span class="pre">after_request()</span></code></a> functions are called.</p></li> <li><p><a class="reference internal" href="../api/#flask.got_request_exception" title="flask.got_request_exception"><code class="xref py py-data docutils literal notranslate"><span class="pre">got_request_exception</span></code></a> is sent when an exception begins to be handled, but before an <a class="reference internal" href="../api/#flask.Flask.errorhandler" title="flask.Flask.errorhandler"><code class="xref py py-meth docutils literal notranslate"><span class="pre">errorhandler()</span></code></a> is looked up or called.</p></li> <li><p><a class="reference internal" href="../api/#flask.request_tearing_down" title="flask.request_tearing_down"><code class="xref py py-data docutils literal notranslate"><span class="pre">request_tearing_down</span></code></a> is sent after the <a class="reference internal" href="../api/#flask.Flask.teardown_request" title="flask.Flask.teardown_request"><code class="xref py py-meth docutils literal notranslate"><span class="pre">teardown_request()</span></code></a> functions are called.</p></li> </ol> </section> </section> <section id="notes-on-proxies"> <span id="id2"></span><h2>Notes On Proxies<a class="headerlink" href="#notes-on-proxies" title="Link to this heading">露</a></h2> <p>Some of the objects provided by Flask are proxies to other objects. The proxies are accessed in the same way for each worker thread, but point to the unique object bound to each worker behind the scenes as described on this page.</p> <p>Most of the time you don鈥檛 have to care about that, but there are some exceptions where it is good to know that this object is actually a proxy:</p> <ul class="simple"> <li><p>The proxy objects cannot fake their type as the actual object types. If you want to perform instance checks, you have to do that on the object being proxied.</p></li> <li><p>The reference to the proxied object is needed in some situations, such as sending <a class="reference internal" href="../signals/"><span class="doc">Signals</span></a> or passing data to a background thread.</p></li> </ul> <p>If you need to access the underlying object that is proxied, use the <code class="xref py py-meth docutils literal notranslate"><span class="pre">_get_current_object()</span></code> method:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">app</span> <span class="o">=</span> <span class="n">current_app</span><span class="o">.</span><span class="n">_get_current_object</span><span class="p">()</span> <span class="n">my_signal</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">app</span><span class="p">)</span> </pre></div> </div> </section> </section> <div class="clearer"></div> </div> </div> </div> <span id="sidebar-top"></span> <div class="sphinxsidebar" role="navigation" aria-label="Main"> <div class="sphinxsidebarwrapper"> <p class="logo"><a href="../"> <img class="logo" src="../_static/flask-vertical.png" alt="Logo of Flask"/> </a></p> <h3>Contents</h3> <ul> <li><a class="reference internal" href="#">The Request Context</a><ul> <li><a class="reference internal" href="#purpose-of-the-context">Purpose of the Context</a></li> <li><a class="reference internal" href="#lifetime-of-the-context">Lifetime of the Context</a></li> <li><a class="reference internal" href="#manually-push-a-context">Manually Push a Context</a></li> <li><a class="reference internal" href="#how-the-context-works">How the Context Works</a></li> <li><a class="reference internal" href="#callbacks-and-errors">Callbacks and Errors</a><ul> <li><a class="reference internal" href="#teardown-callbacks">Teardown Callbacks</a></li> <li><a class="reference internal" href="#signals">Signals</a></li> </ul> </li> <li><a class="reference internal" href="#notes-on-proxies">Notes On Proxies</a></li> </ul> </li> </ul> <h3>Navigation</h3> <ul> <li><a href="../">Overview</a> <ul> <li>Previous: <a href="../appcontext/" title="previous chapter">The Application Context</a> <li>Next: <a href="../blueprints/" title="next chapter">Modular Applications with Blueprints</a> </ul> </li> </ul> <search id="searchbox" style="display: none" role="search"> <h3 id="searchlabel">Quick search</h3> <div class="searchformwrapper"> <form class="search" action="../search/" method="get"> <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/> <input type="submit" value="Go" /> </form> </div> </search> <script>document.getElementById('searchbox').style.display = "block"</script><div id="ethical-ad-placement"></div> </div> </div> <div class="clearer"></div> </div> <div class="footer" role="contentinfo"> &#169; Copyright 2010 Pallets. Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.1.3. </div> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10