Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 192 lines (150 sloc) 8.984 kb
c0abdc4 @mitsuhiko Interlinked design docs better
authored
1 .. _design:
2
190059c @mitsuhiko Added support for macro pulling and documented certain design decisions.
authored
3 Design Decisions in Flask
4 =========================
5
6 If you are curious why Flask does certain things the way it does and not
a7ff9db Proofreading the documentation
Chris Edgemon authored
7 differently, this section is for you. This should give you an idea about
190059c @mitsuhiko Added support for macro pulling and documented certain design decisions.
authored
8 some of the design decisions that may appear arbitrary and surprising at
9 first, especially in direct comparison with other frameworks.
10
11
12 The Explicit Application Object
13 -------------------------------
14
15 A Python web application based on WSGI has to have one central callable
16 object that implements the actual application. In Flask this is an
17 instance of the :class:`~flask.Flask` class. Each Flask application has
18 to create an instance of this class itself and pass it the name of the
19 module, but why can't Flask do that itself?
20
21 Without such an explicit application object the following code::
22
23 from flask import Flask
24 app = Flask(__name__)
25
26 @app.route('/')
27 def index():
28 return 'Hello World!'
29
30 Would look like this instead::
31
32 from hypothetical_flask import route
33
34 @route('/')
35 def index():
36 return 'Hello World!'
37
38 There are three major reasons for this. The most important one is that
63caf6e @birkenfeld Fix some typos.
birkenfeld authored
39 implicit application objects require that there may only be one instance at
40 the time. There are ways to fake multiple applications with a single
190059c @mitsuhiko Added support for macro pulling and documented certain design decisions.
authored
41 application object, like maintaining a stack of applications, but this
42 causes some problems I won't outline here in detail. Now the question is:
43 when does a microframework need more than one application at the same
44 time? A good example for this is unittesting. When you want to test
45 something it can be very helpful to create a minimal application to test
46 specific behavior. When the application object is deleted everything it
47 allocated will be freed again.
48
63caf6e @birkenfeld Fix some typos.
birkenfeld authored
49 Another thing that becomes possible when you have an explicit object lying
190059c @mitsuhiko Added support for macro pulling and documented certain design decisions.
authored
50 around in your code is that you can subclass the base class
a3cb2a3 @rduplain Use American English for "behavior" in docs.
rduplain authored
51 (:class:`~flask.Flask`) to alter specific behavior. This would not be
a7ff9db Proofreading the documentation
Chris Edgemon authored
52 possible without hacks if the object were created ahead of time for you
190059c @mitsuhiko Added support for macro pulling and documented certain design decisions.
authored
53 based on a class that is not exposed to you.
54
55 But there is another very important reason why Flask depends on an
93a8ca0 @rduplain Fixed some minor typos throughout docs.
rduplain authored
56 explicit instantiation of that class: the package name. Whenever you
190059c @mitsuhiko Added support for macro pulling and documented certain design decisions.
authored
57 create a Flask instance you usually pass it `__name__` as package name.
58 Flask depends on that information to properly load resources relative
59 to your module. With Python's outstanding support for reflection it can
60 then access the package to figure out where the templates and static files
61 are stored (see :meth:`~flask.Flask.open_resource`). Now obviously there
62 are frameworks around that do not need any configuration and will still be
63 able to load templates relative to your application module. But they have
64 to use the current working directory for that, which is a very unreliable
65 way to determine where the application is. The current working directory
66 is process-wide and if you are running multiple applications in one
67 process (which could happen in a webserver without you knowing) the paths
68 will be off. Worse: many webservers do not set the working directory to
69 the directory of your application but to the document root which does not
70 have to be the same folder.
71
72 The third reason is "explicit is better than implicit". That object is
73 your WSGI application, you don't have to remember anything else. If you
74 want to apply a WSGI middleware, just wrap it and you're done (though
75 there are better ways to do that so that you do not lose the reference
76 to the application object :meth:`~flask.Flask.wsgi_app`).
77
fe35105 @mitsuhiko Updated design decisions. This fixes #63
authored
78 Furthermore this design makes it possible to use a factory function to
79 create the application which is very helpful for unittesting and similar
80 things (:ref:`app-factories`).
81
08bf538 @mitsuhiko Added a note on the behaviour of the routing system
authored
82 The Routing System
83 ------------------
84
85 Flask uses the Werkzeug routing system which has was designed to
86 automatically order routes by complexity. This means that you can declare
87 routes in arbitrary order and they will still work as expected. This is a
88 requirement if you want to properly implement decorator based routing
89 since decorators could be fired in undefined order when the application is
90 split into multiple modules.
91
92 Another design decision with the Werkzeug routing system is that routes
40ccc0a Fixing some wording in the design documentation.
Randall Degges authored
93 in Werkzeug try to ensure that URLs are unique. Werkzeug will go quite far
94 with that in that it will automatically redirect to a canonical URL if a route
95 is ambiguous.
08bf538 @mitsuhiko Added a note on the behaviour of the routing system
authored
96
97
190059c @mitsuhiko Added support for macro pulling and documented certain design decisions.
authored
98 One Template Engine
99 -------------------
100
101 Flask decides on one template engine: Jinja2. Why doesn't Flask have a
102 pluggable template engine interface? You can obviously use a different
103 template engine, but Flask will still configure Jinja2 for you. While
104 that limitation that Jinja2 is *always* configured will probably go away,
105 the decision to bundle one template engine and use that will not.
106
107 Template engines are like programming languages and each of those engines
a7ff9db Proofreading the documentation
Chris Edgemon authored
108 has a certain understanding about how things work. On the surface they
190059c @mitsuhiko Added support for macro pulling and documented certain design decisions.
authored
109 all work the same: you tell the engine to evaluate a template with a set
110 of variables and take the return value as string.
111
112 But that's about where similarities end. Jinja2 for example has an
113 extensive filter system, a certain way to do template inheritance, support
114 for reusable blocks (macros) that can be used from inside templates and
a224fec @birkenfeld More typo fixes.
birkenfeld authored
115 also from Python code, uses Unicode for all operations, supports
190059c @mitsuhiko Added support for macro pulling and documented certain design decisions.
authored
116 iterative template rendering, configurable syntax and more. On the other
117 hand an engine like Genshi is based on XML stream evaluation, template
118 inheritance by taking the availability of XPath into account and more.
119 Mako on the other hand treats templates similar to Python modules.
120
a224fec @birkenfeld More typo fixes.
birkenfeld authored
121 When it comes to connecting a template engine with an application or
a7ff9db Proofreading the documentation
Chris Edgemon authored
122 framework there is more than just rendering templates. For instance,
a224fec @birkenfeld More typo fixes.
birkenfeld authored
123 Flask uses Jinja2's extensive autoescaping support. Also it provides
a7ff9db Proofreading the documentation
Chris Edgemon authored
124 ways to access macros from Jinja2 templates.
190059c @mitsuhiko Added support for macro pulling and documented certain design decisions.
authored
125
126 A template abstraction layer that would not take the unique features of
127 the template engines away is a science on its own and a too large
128 undertaking for a microframework like Flask.
129
c0abdc4 @mitsuhiko Interlinked design docs better
authored
130 Furthermore extensions can then easily depend on one template language
131 being present. You can easily use your own templating language, but an
132 extension could still depend on Jinja itself.
133
190059c @mitsuhiko Added support for macro pulling and documented certain design decisions.
authored
134
135 Micro with Dependencies
136 -----------------------
137
138 Why does Flask call itself a microframework and yet it depends on two
139 libraries (namely Werkzeug and Jinja2). Why shouldn't it? If we look
140 over to the Ruby side of web development there we have a protocol very
141 similar to WSGI. Just that it's called Rack there, but besides that it
142 looks very much like a WSGI rendition for Ruby. But nearly all
143 applications in Ruby land do not work with Rack directly, but on top of a
a7ff9db Proofreading the documentation
Chris Edgemon authored
144 library with the same name. This Rack library has two equivalents in
190059c @mitsuhiko Added support for macro pulling and documented certain design decisions.
authored
145 Python: WebOb (formerly Paste) and Werkzeug. Paste is still around but
a7ff9db Proofreading the documentation
Chris Edgemon authored
146 from my understanding it's sort of deprecated in favour of WebOb. The
190059c @mitsuhiko Added support for macro pulling and documented certain design decisions.
authored
147 development of WebOb and Werkzeug started side by side with similar ideas
148 in mind: be a good implementation of WSGI for other applications to take
149 advantage.
150
151 Flask is a framework that takes advantage of the work already done by
152 Werkzeug to properly interface WSGI (which can be a complex task at
153 times). Thanks to recent developments in the Python package
93a8ca0 @rduplain Fixed some minor typos throughout docs.
rduplain authored
154 infrastructure, packages with dependencies are no longer an issue and
190059c @mitsuhiko Added support for macro pulling and documented certain design decisions.
authored
155 there are very few reasons against having libraries that depend on others.
156
157
158 Thread Locals
159 -------------
160
161 Flask uses thread local objects (context local objects in fact, they
162 support greenlet contexts as well) for request, session and an extra
163 object you can put your own things on (:data:`~flask.g`). Why is that and
164 isn't that a bad idea?
165
166 Yes it is usually not such a bright idea to use thread locals. They cause
167 troubles for servers that are not based on the concept of threads and make
168 large applications harder to maintain. However Flask is just not designed
93a8ca0 @rduplain Fixed some minor typos throughout docs.
rduplain authored
169 for large applications or asynchronous servers. Flask wants to make it
190059c @mitsuhiko Added support for macro pulling and documented certain design decisions.
authored
170 quick and easy to write a traditional web application.
171
172 Also see the :ref:`becomingbig` section of the documentation for some
173 inspiration for larger applications based on Flask.
fe35105 @mitsuhiko Updated design decisions. This fixes #63
authored
174
175
176 What Flask is, What Flask is Not
177 --------------------------------
178
179 Flask will never have a database layer. It will not have a form library
180 or anything else in that direction. Flask itself just bridges to Werkzeug
181 to implement a proper WSGI application and to Jinja2 to handle templating.
182 It also binds to a few common standard library packages such as logging.
183 Everything else is up for extensions.
184
185 Why is this the case? Because people have different preferences and
186 requirements and Flask could not meet those if it would force any of this
187 into the core. The majority of web applications will need a template
188 engine in some sort. However not every application needs a SQL database.
189
190 The idea of Flask is to build a good foundation for all applications.
191 Everything else is up to you or extensions.
Something went wrong with that request. Please try again.