<h1>Application Structure and Lifecycle<aclass="headerlink"href="#application-structure-and-lifecycle"title="Link to this heading">¶</a></h1>
<p>Flask makes it pretty easy to write a web application. But there are quite a few
different parts to an application and to each request it handles. Knowing what happens
during application setup, serving, and handling requests will help you know what’s
possible in Flask and how to structure your application.</p>
<sectionid="application-setup">
<h2>Application Setup<aclass="headerlink"href="#application-setup"title="Link to this heading">¶</a></h2>
<p>The first step in creating a Flask application is creating the application object. Each
Flask application is an instance of the <aclass="reference internal"href="api.html#flask.Flask"title="flask.Flask"><codeclass="xref py py-class docutils literal notranslate"><spanclass="pre">Flask</span></code></a> class, which collects all
<p>This is known as the “application setup phase”, it’s the code you write that’s outside
any view functions or other handlers. It can be split up between different modules and
sub-packages, but all code that you want to be part of your application must be imported
in order for it to be registered.</p>
<p>All application setup must be completed before you start serving your application and
handling requests. This is because WSGI servers divide work between multiple workers, or
can be distributed across multiple machines. If the configuration changed in one worker,
there’s no way for Flask to ensure consistency between other workers.</p>
<p>Flask tries to help developers catch some of these setup ordering issues by showing an
error if setup-related methods are called after requests are handled. In that case
you’ll see this error:</p>
<blockquote>
<div><p>The setup method ‘route’ can no longer be called on the application. It has already
handled its first request, any changes will not be applied consistently.
Make sure all imports, decorators, functions, etc. needed to set up the application
are done before running it.</p>
</div></blockquote>
<p>However, it is not possible for Flask to detect all cases of out-of-order setup. In
general, don’t do anything to modify the <codeclass="docutils literal notranslate"><spanclass="pre">Flask</span></code> app object and <codeclass="docutils literal notranslate"><spanclass="pre">Blueprint</span></code> objects
from within view functions that run during requests. This includes:</p>
<ulclass="simple">
<li><p>Adding routes, view functions, and other request handlers with <codeclass="docutils literal notranslate"><spanclass="pre">@app.route</span></code>,
<li><p>Loading configuration with <codeclass="docutils literal notranslate"><spanclass="pre">app.config</span></code>.</p></li>
<li><p>Setting up the Jinja template environment with <codeclass="docutils literal notranslate"><spanclass="pre">app.jinja_env</span></code>.</p></li>
<li><p>Setting a session interface, instead of the default itsdangerous cookie.</p></li>
<li><p>Setting a JSON provider with <codeclass="docutils literal notranslate"><spanclass="pre">app.json</span></code>, instead of the default provider.</p></li>
<li><p>Creating and initializing Flask extensions.</p></li>
<h2>Serving the Application<aclass="headerlink"href="#serving-the-application"title="Link to this heading">¶</a></h2>
<p>Flask is a WSGI application framework. The other half of WSGI is the WSGI server. During
development, Flask, through Werkzeug, provides a development WSGI server with the
<codeclass="docutils literal notranslate"><spanclass="pre">flask</span><spanclass="pre">run</span></code> CLI command. When you are done with development, use a production server
to serve your application, see <aclass="reference internal"href="deploying/index.html"><spanclass="doc">Deploying to Production</span></a>.</p>
<p>Regardless of what server you’re using, it will follow the <spanclass="target"id="index-0"></span><aclass="pep reference external"href="https://peps.python.org/pep-3333/"><strong>PEP 3333</strong></a> WSGI spec. The
WSGI server will be told how to access your Flask application object, which is the WSGI
application. Then it will start listening for HTTP requests, translate the request data
into a WSGI environ, and call the WSGI application with that data. The WSGI application
will return data that is translated into an HTTP response.</p>
<olclass="arabic simple">
<li><p>Browser or other client makes HTTP request.</p></li>
<li><p>WSGI server receives request.</p></li>
<li><p>WSGI server converts HTTP data to WSGI <codeclass="docutils literal notranslate"><spanclass="pre">environ</span></code> dict.</p></li>
<li><p>WSGI server calls WSGI application with the <codeclass="docutils literal notranslate"><spanclass="pre">environ</span></code>.</p></li>
<li><p>Flask, the WSGI application, does all its internal processing to route the request
to a view function, handle errors, etc.</p></li>
<li><p>Flask translates View function return into WSGI response data, passes it to WSGI
server.</p></li>
<li><p>WSGI server creates and send an HTTP response.</p></li>
<li><p>Client receives the HTTP response.</p></li>
</ol>
<sectionid="middleware">
<h3>Middleware<aclass="headerlink"href="#middleware"title="Link to this heading">¶</a></h3>
<p>The WSGI application above is a callable that behaves in a certain way. Middleware
is a WSGI application that wraps another WSGI application. It’s a similar concept to
Python decorators. The outermost middleware will be called by the server. It can modify
the data passed to it, then call the WSGI application (or further middleware) that it
wraps, and so on. And it can take the return value of that call and modify it further.</p>
<p>From the WSGI server’s perspective, there is one WSGI application, the one it calls
directly. Typically, Flask is the “real” application at the end of the chain of
middleware. But even Flask can call further WSGI applications, although that’s an
advanced, uncommon use case.</p>
<p>A common middleware you’ll see used with Flask is Werkzeug’s
<aclass="reference external"href="https://werkzeug.palletsprojects.com/en/stable/middleware/proxy_fix/#werkzeug.middleware.proxy_fix.ProxyFix"title="(in Werkzeug v3.1.x)"><codeclass="xref py py-class docutils literal notranslate"><spanclass="pre">ProxyFix</span></code></a>, which modifies the request to look
like it came directly from a client even if it passed through HTTP proxies on the way.
There are other middleware that can handle serving static files, authentication, etc.</p>
</section>
</section>
<sectionid="how-a-request-is-handled">
<h2>How a Request is Handled<aclass="headerlink"href="#how-a-request-is-handled"title="Link to this heading">¶</a></h2>
<p>For us, the interesting part of the steps above is when Flask gets called by the WSGI
server (or middleware). At that point, it will do quite a lot to handle the request and
generate the response. At the most basic, it will match the URL to a view function, call
the view function, and pass the return value back to the server. But there are many more
parts that you can use to customize its behavior.</p>
<olclass="arabic simple">
<li><p>WSGI server calls the Flask object, which calls <aclass="reference internal"href="api.html#flask.Flask.wsgi_app"title="flask.Flask.wsgi_app"><codeclass="xref py py-meth docutils literal notranslate"><spanclass="pre">Flask.wsgi_app()</span></code></a>.</p></li>
<li><p>A <aclass="reference internal"href="api.html#flask.ctx.RequestContext"title="flask.ctx.RequestContext"><codeclass="xref py py-class docutils literal notranslate"><spanclass="pre">RequestContext</span></code></a> object is created. This converts the WSGI <codeclass="docutils literal notranslate"><spanclass="pre">environ</span></code>
dict into a <aclass="reference internal"href="api.html#flask.Request"title="flask.Request"><codeclass="xref py py-class docutils literal notranslate"><spanclass="pre">Request</span></code></a> object. It also creates an <codeclass="xref py py-class docutils literal notranslate"><spanclass="pre">AppContext</span></code> object.</p></li>
<li><p>The <aclass="reference internal"href="appcontext.html"><spanclass="doc">app context</span></a> is pushed, which makes <aclass="reference internal"href="api.html#flask.current_app"title="flask.current_app"><codeclass="xref py py-data docutils literal notranslate"><spanclass="pre">current_app</span></code></a> and
<li><p>The <aclass="reference internal"href="api.html#flask.appcontext_pushed"title="flask.appcontext_pushed"><codeclass="xref py py-data docutils literal notranslate"><spanclass="pre">appcontext_pushed</span></code></a> signal is sent.</p></li>
<li><p>The <aclass="reference internal"href="reqcontext.html"><spanclass="doc">request context</span></a> is pushed, which makes <aclass="reference internal"href="api.html#flask.request"title="flask.request"><codeclass="xref py py-attr docutils literal notranslate"><spanclass="pre">request</span></code></a> and
<li><p>The session is opened, loading any existing session data using the app’s
<aclass="reference internal"href="api.html#flask.Flask.session_interface"title="flask.Flask.session_interface"><codeclass="xref py py-attr docutils literal notranslate"><spanclass="pre">session_interface</span></code></a>, an instance of <aclass="reference internal"href="api.html#flask.sessions.SessionInterface"title="flask.sessions.SessionInterface"><codeclass="xref py py-class docutils literal notranslate"><spanclass="pre">SessionInterface</span></code></a>.</p></li>
<li><p>The URL is matched against the URL rules registered with the <aclass="reference internal"href="api.html#flask.Flask.route"title="flask.Flask.route"><codeclass="xref py py-meth docutils literal notranslate"><spanclass="pre">route()</span></code></a>
decorator during application setup. If there is no match, the error - usually a 404,
405, or redirect - is stored to be handled later.</p></li>
<li><p>The <aclass="reference internal"href="api.html#flask.request_started"title="flask.request_started"><codeclass="xref py py-data docutils literal notranslate"><spanclass="pre">request_started</span></code></a> signal is sent.</p></li>
<li><p>Any <aclass="reference internal"href="api.html#flask.Flask.before_request"title="flask.Flask.before_request"><codeclass="xref py py-meth docutils literal notranslate"><spanclass="pre">before_request()</span></code></a> decorated functions are called. If any of
these function returns a value it is treated as the response immediately.</p></li>
<li><p>If the URL didn’t match a route a few steps ago, that error is raised now.</p></li>
<li><p>The <aclass="reference internal"href="api.html#flask.Flask.route"title="flask.Flask.route"><codeclass="xref py py-meth docutils literal notranslate"><spanclass="pre">route()</span></code></a> decorated view function associated with the matched URL
is called and returns a value to be used as the response.</p></li>
<li><p>If any step so far raised an exception, and there is an <aclass="reference internal"href="api.html#flask.Flask.errorhandler"title="flask.Flask.errorhandler"><codeclass="xref py py-meth docutils literal notranslate"><spanclass="pre">errorhandler()</span></code></a>
decorated function that matches the exception class or HTTP error code, it is
called to handle the error and return a response.</p></li>
<li><p>Whatever returned a response value - a before request function, the view, or an
error handler, that value is converted to a <aclass="reference internal"href="api.html#flask.Response"title="flask.Response"><codeclass="xref py py-class docutils literal notranslate"><spanclass="pre">Response</span></code></a> object.</p></li>
<li><p>Any <aclass="reference internal"href="api.html#flask.after_this_request"title="flask.after_this_request"><codeclass="xref py py-func docutils literal notranslate"><spanclass="pre">after_this_request()</span></code></a> decorated functions are called, then cleared.</p></li>
<li><p>Any <aclass="reference internal"href="api.html#flask.Flask.after_request"title="flask.Flask.after_request"><codeclass="xref py py-meth docutils literal notranslate"><spanclass="pre">after_request()</span></code></a> decorated functions are called, which can modify
the response object.</p></li>
<li><p>The session is saved, persisting any modified session data using the app’s
<li><p>The <aclass="reference internal"href="api.html#flask.request_finished"title="flask.request_finished"><codeclass="xref py py-data docutils literal notranslate"><spanclass="pre">request_finished</span></code></a> signal is sent.</p></li>
<li><p>If any step so far raised an exception, and it was not handled by an error handler
function, it is handled now. HTTP exceptions are treated as responses with their
corresponding status code, other exceptions are converted to a generic 500 response.
The <aclass="reference internal"href="api.html#flask.got_request_exception"title="flask.got_request_exception"><codeclass="xref py py-data docutils literal notranslate"><spanclass="pre">got_request_exception</span></code></a> signal is sent.</p></li>
<li><p>The response object’s status, headers, and body are returned to the WSGI server.</p></li>