| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | Design Decisions in Flask
 | 
					
						
							|  |  |  | =========================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you are curious why Flask does certain things the way it does and not
 | 
					
						
							| 
									
										
										
										
											2010-04-20 12:25:51 +08:00
										 |  |  | differently, this section is for you.  This should give you an idea about
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | some of the design decisions that may appear arbitrary and surprising at
 | 
					
						
							|  |  |  | first, especially in direct comparison with other frameworks.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The Explicit Application Object
 | 
					
						
							|  |  |  | -------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A Python web application based on WSGI has to have one central callable
 | 
					
						
							|  |  |  | object that implements the actual application.  In Flask this is an
 | 
					
						
							|  |  |  | instance of the :class:`~flask.Flask` class.  Each Flask application has
 | 
					
						
							|  |  |  | to create an instance of this class itself and pass it the name of the
 | 
					
						
							|  |  |  | module, but why can't Flask do that itself?
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Without such an explicit application object the following code::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     from flask import Flask
 | 
					
						
							|  |  |  |     app = Flask(__name__)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @app.route('/')
 | 
					
						
							|  |  |  |     def index():
 | 
					
						
							|  |  |  |         return 'Hello World!'
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Would look like this instead::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     from hypothetical_flask import route
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @route('/')
 | 
					
						
							|  |  |  |     def index():
 | 
					
						
							|  |  |  |         return 'Hello World!'
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | There are three major reasons for this.  The most important one is that
 | 
					
						
							| 
									
										
										
										
											2010-05-30 01:53:08 +08:00
										 |  |  | implicit application objects require that there may only be one instance at
 | 
					
						
							|  |  |  | the time.  There are ways to fake multiple applications with a single
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | application object, like maintaining a stack of applications, but this
 | 
					
						
							|  |  |  | causes some problems I won't outline here in detail.  Now the question is:
 | 
					
						
							|  |  |  | when does a microframework need more than one application at the same
 | 
					
						
							| 
									
										
										
										
											2019-05-15 04:08:00 +08:00
										 |  |  | time?  A good example for this is unit testing.  When you want to test
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | something it can be very helpful to create a minimal application to test
 | 
					
						
							|  |  |  | specific behavior.  When the application object is deleted everything it
 | 
					
						
							|  |  |  | allocated will be freed again.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-30 01:53:08 +08:00
										 |  |  | Another thing that becomes possible when you have an explicit object lying
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | around in your code is that you can subclass the base class
 | 
					
						
							| 
									
										
										
										
											2012-04-19 23:51:38 +08:00
										 |  |  | (:class:`~flask.Flask`) to alter specific behavior.  This would not be
 | 
					
						
							| 
									
										
										
										
											2010-04-20 12:25:51 +08:00
										 |  |  | possible without hacks if the object were created ahead of time for you
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | based on a class that is not exposed to you.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | But there is another very important reason why Flask depends on an
 | 
					
						
							| 
									
										
										
										
											2010-05-12 09:18:42 +08:00
										 |  |  | explicit instantiation of that class: the package name.  Whenever you
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | create a Flask instance you usually pass it `__name__` as package name.
 | 
					
						
							|  |  |  | Flask depends on that information to properly load resources relative
 | 
					
						
							|  |  |  | to your module.  With Python's outstanding support for reflection it can
 | 
					
						
							|  |  |  | then access the package to figure out where the templates and static files
 | 
					
						
							|  |  |  | are stored (see :meth:`~flask.Flask.open_resource`).  Now obviously there
 | 
					
						
							|  |  |  | are frameworks around that do not need any configuration and will still be
 | 
					
						
							|  |  |  | able to load templates relative to your application module.  But they have
 | 
					
						
							|  |  |  | to use the current working directory for that, which is a very unreliable
 | 
					
						
							|  |  |  | way to determine where the application is.  The current working directory
 | 
					
						
							|  |  |  | is process-wide and if you are running multiple applications in one
 | 
					
						
							|  |  |  | process (which could happen in a webserver without you knowing) the paths
 | 
					
						
							|  |  |  | will be off.  Worse: many webservers do not set the working directory to
 | 
					
						
							|  |  |  | the directory of your application but to the document root which does not
 | 
					
						
							|  |  |  | have to be the same folder.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The third reason is "explicit is better than implicit".  That object is
 | 
					
						
							|  |  |  | your WSGI application, you don't have to remember anything else.  If you
 | 
					
						
							|  |  |  | want to apply a WSGI middleware, just wrap it and you're done (though
 | 
					
						
							|  |  |  | there are better ways to do that so that you do not lose the reference
 | 
					
						
							|  |  |  | to the application object :meth:`~flask.Flask.wsgi_app`).
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-18 23:03:31 +08:00
										 |  |  | Furthermore this design makes it possible to use a factory function to
 | 
					
						
							| 
									
										
										
										
											2019-05-15 04:08:00 +08:00
										 |  |  | create the application which is very helpful for unit testing and similar
 | 
					
						
							| 
									
										
										
										
											2020-04-05 03:57:14 +08:00
										 |  |  | things (:doc:`/patterns/appfactories`).
 | 
					
						
							| 
									
										
										
										
											2010-06-18 23:03:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-27 06:36:53 +08:00
										 |  |  | The Routing System
 | 
					
						
							|  |  |  | ------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-03 20:11:43 +08:00
										 |  |  | Flask uses the Werkzeug routing system which was designed to
 | 
					
						
							| 
									
										
										
										
											2011-08-27 06:36:53 +08:00
										 |  |  | automatically order routes by complexity.  This means that you can declare
 | 
					
						
							|  |  |  | routes in arbitrary order and they will still work as expected.  This is a
 | 
					
						
							|  |  |  | requirement if you want to properly implement decorator based routing
 | 
					
						
							|  |  |  | since decorators could be fired in undefined order when the application is
 | 
					
						
							|  |  |  | split into multiple modules.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Another design decision with the Werkzeug routing system is that routes
 | 
					
						
							| 
									
										
										
										
											2012-07-21 05:29:10 +08:00
										 |  |  | in Werkzeug try to ensure that URLs are unique.  Werkzeug will go quite far
 | 
					
						
							|  |  |  | with that in that it will automatically redirect to a canonical URL if a route
 | 
					
						
							|  |  |  | is ambiguous.
 | 
					
						
							| 
									
										
										
										
											2011-08-27 06:36:53 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | One Template Engine
 | 
					
						
							|  |  |  | -------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-20 01:43:16 +08:00
										 |  |  | Flask decides on one template engine: Jinja.  Why doesn't Flask have a
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | pluggable template engine interface?  You can obviously use a different
 | 
					
						
							| 
									
										
										
										
											2025-08-20 01:43:16 +08:00
										 |  |  | template engine, but Flask will still configure Jinja for you.  While
 | 
					
						
							|  |  |  | that limitation that Jinja is *always* configured will probably go away,
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | the decision to bundle one template engine and use that will not.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Template engines are like programming languages and each of those engines
 | 
					
						
							| 
									
										
										
										
											2010-04-20 12:25:51 +08:00
										 |  |  | has a certain understanding about how things work.  On the surface they
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | all work the same: you tell the engine to evaluate a template with a set
 | 
					
						
							|  |  |  | of variables and take the return value as string.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-20 01:43:16 +08:00
										 |  |  | But that's about where similarities end. Jinja for example has an
 | 
					
						
							| 
									
										
										
										
											2020-04-04 02:58:16 +08:00
										 |  |  | extensive filter system, a certain way to do template inheritance,
 | 
					
						
							|  |  |  | support for reusable blocks (macros) that can be used from inside
 | 
					
						
							|  |  |  | templates and also from Python code, supports iterative template
 | 
					
						
							|  |  |  | rendering, configurable syntax and more. On the other hand an engine
 | 
					
						
							|  |  |  | like Genshi is based on XML stream evaluation, template inheritance by
 | 
					
						
							|  |  |  | taking the availability of XPath into account and more. Mako on the
 | 
					
						
							|  |  |  | other hand treats templates similar to Python modules.
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-30 02:06:12 +08:00
										 |  |  | When it comes to connecting a template engine with an application or
 | 
					
						
							| 
									
										
										
										
											2010-04-20 12:25:51 +08:00
										 |  |  | framework there is more than just rendering templates.  For instance,
 | 
					
						
							| 
									
										
										
										
											2025-08-20 01:43:16 +08:00
										 |  |  | Flask uses Jinja's extensive autoescaping support.  Also it provides
 | 
					
						
							|  |  |  | ways to access macros from Jinja templates.
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | A template abstraction layer that would not take the unique features of
 | 
					
						
							|  |  |  | the template engines away is a science on its own and a too large
 | 
					
						
							|  |  |  | undertaking for a microframework like Flask.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-19 04:01:11 +08:00
										 |  |  | Furthermore extensions can then easily depend on one template language
 | 
					
						
							|  |  |  | being present.  You can easily use your own templating language, but an
 | 
					
						
							|  |  |  | extension could still depend on Jinja itself.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-06 02:28:22 +08:00
										 |  |  | What does "micro" mean?
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | -----------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-06 02:28:22 +08:00
										 |  |  | “Micro” does not mean that your whole web application has to fit into a single
 | 
					
						
							|  |  |  | Python file (although it certainly can), nor does it mean that Flask is lacking
 | 
					
						
							|  |  |  | in functionality. The "micro" in microframework means Flask aims to keep the
 | 
					
						
							|  |  |  | core simple but extensible. Flask won't make many decisions for you, such as
 | 
					
						
							|  |  |  | what database to use. Those decisions that it does make, such as what
 | 
					
						
							|  |  |  | templating engine to use, are easy to change.  Everything else is up to you, so
 | 
					
						
							|  |  |  | that Flask can be everything you need and nothing you don't.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | By default, Flask does not include a database abstraction layer, form
 | 
					
						
							|  |  |  | validation or anything else where different libraries already exist that can
 | 
					
						
							|  |  |  | handle that. Instead, Flask supports extensions to add such functionality to
 | 
					
						
							|  |  |  | your application as if it was implemented in Flask itself. Numerous extensions
 | 
					
						
							|  |  |  | provide database integration, form validation, upload handling, various open
 | 
					
						
							|  |  |  | authentication technologies, and more. Flask may be "micro", but it's ready for
 | 
					
						
							|  |  |  | production use on a variety of needs.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | Why does Flask call itself a microframework and yet it depends on two
 | 
					
						
							| 
									
										
										
										
											2025-08-20 01:43:16 +08:00
										 |  |  | libraries (namely Werkzeug and Jinja).  Why shouldn't it?  If we look
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | over to the Ruby side of web development there we have a protocol very
 | 
					
						
							|  |  |  | similar to WSGI.  Just that it's called Rack there, but besides that it
 | 
					
						
							|  |  |  | looks very much like a WSGI rendition for Ruby.  But nearly all
 | 
					
						
							|  |  |  | applications in Ruby land do not work with Rack directly, but on top of a
 | 
					
						
							| 
									
										
										
										
											2010-04-20 12:25:51 +08:00
										 |  |  | library with the same name.  This Rack library has two equivalents in
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | Python: WebOb (formerly Paste) and Werkzeug.  Paste is still around but
 | 
					
						
							| 
									
										
										
										
											2010-04-20 12:25:51 +08:00
										 |  |  | from my understanding it's sort of deprecated in favour of WebOb.  The
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | development of WebOb and Werkzeug started side by side with similar ideas
 | 
					
						
							|  |  |  | in mind: be a good implementation of WSGI for other applications to take
 | 
					
						
							|  |  |  | advantage.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Flask is a framework that takes advantage of the work already done by
 | 
					
						
							|  |  |  | Werkzeug to properly interface WSGI (which can be a complex task at
 | 
					
						
							|  |  |  | times).  Thanks to recent developments in the Python package
 | 
					
						
							| 
									
										
										
										
											2010-05-12 09:18:42 +08:00
										 |  |  | infrastructure, packages with dependencies are no longer an issue and
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | there are very few reasons against having libraries that depend on others.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-13 05:52:03 +08:00
										 |  |  | Context Locals
 | 
					
						
							|  |  |  | --------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Flask uses special context locals and proxies to provide access to the
 | 
					
						
							|  |  |  | current app and request data to any code running during a request, CLI command,
 | 
					
						
							|  |  |  | etc. Context locals are specific to the worker handling the activity, such as a
 | 
					
						
							|  |  |  | thread, process, coroutine, or greenlet.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The context and proxies help solve two development issues: circular imports, and
 | 
					
						
							|  |  |  | passing around global data. :data:`.current_app: can be used to access the
 | 
					
						
							|  |  |  | application object without needing to import the app object directly, avoiding
 | 
					
						
							|  |  |  | circular import issues. :data:`.request`, :data:`.session`, and :data`.g` can be
 | 
					
						
							|  |  |  | imported to access the current data for the request, rather than needing to
 | 
					
						
							|  |  |  | pass them as arguments through every single function in your project.
 | 
					
						
							| 
									
										
										
										
											2010-04-18 21:44:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-18 23:03:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-07 06:31:28 +08:00
										 |  |  | Async/await and ASGI support
 | 
					
						
							| 
									
										
										
										
											2020-07-07 03:54:26 +08:00
										 |  |  | ----------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-07 06:31:28 +08:00
										 |  |  | Flask supports ``async`` coroutines for view functions by executing the
 | 
					
						
							|  |  |  | coroutine on a separate thread instead of using an event loop on the
 | 
					
						
							|  |  |  | main thread as an async-first (ASGI) framework would. This is necessary
 | 
					
						
							|  |  |  | for Flask to remain backwards compatible with extensions and code built
 | 
					
						
							|  |  |  | before ``async`` was introduced into Python. This compromise introduces
 | 
					
						
							|  |  |  | a performance cost compared with the ASGI frameworks, due to the
 | 
					
						
							|  |  |  | overhead of the threads.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Due to how tied to WSGI Flask's code is, it's not clear if it's possible
 | 
					
						
							|  |  |  | to make the ``Flask`` class support ASGI and WSGI at the same time. Work
 | 
					
						
							|  |  |  | is currently being done in Werkzeug to work with ASGI, which may
 | 
					
						
							|  |  |  | eventually enable support in Flask as well.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | See :doc:`/async-await` for more discussion.
 | 
					
						
							| 
									
										
										
										
											2020-07-07 03:54:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-18 23:03:31 +08:00
										 |  |  | What Flask is, What Flask is Not
 | 
					
						
							|  |  |  | --------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Flask will never have a database layer.  It will not have a form library
 | 
					
						
							|  |  |  | or anything else in that direction.  Flask itself just bridges to Werkzeug
 | 
					
						
							| 
									
										
										
										
											2025-08-20 01:43:16 +08:00
										 |  |  | to implement a proper WSGI application and to Jinja to handle templating.
 | 
					
						
							| 
									
										
										
										
											2010-06-18 23:03:31 +08:00
										 |  |  | It also binds to a few common standard library packages such as logging.
 | 
					
						
							|  |  |  | Everything else is up for extensions.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Why is this the case?  Because people have different preferences and
 | 
					
						
							|  |  |  | requirements and Flask could not meet those if it would force any of this
 | 
					
						
							|  |  |  | into the core.  The majority of web applications will need a template
 | 
					
						
							|  |  |  | engine in some sort.  However not every application needs a SQL database.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-06 02:28:22 +08:00
										 |  |  | As your codebase grows, you are free to make the design decisions appropriate
 | 
					
						
							|  |  |  | for your project.  Flask will continue to provide a very simple glue layer to
 | 
					
						
							|  |  |  | the best that Python has to offer.  You can implement advanced patterns in
 | 
					
						
							|  |  |  | SQLAlchemy or another database tool, introduce non-relational data persistence
 | 
					
						
							|  |  |  | as appropriate, and take advantage of framework-agnostic tools built for WSGI,
 | 
					
						
							|  |  |  | the Python web interface.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-18 23:03:31 +08:00
										 |  |  | The idea of Flask is to build a good foundation for all applications.
 | 
					
						
							|  |  |  | Everything else is up to you or extensions.
 |