| 
									
										
										
										
											2010-04-09 19:40:05 +08:00
										 |  |  | .. _quickstart:
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | Quickstart
 | 
					
						
							|  |  |  | ==========
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  | Eager to get started?  This page gives a good introduction to Flask.  It
 | 
					
						
							|  |  |  | assumes you already have Flask installed.  If you do not, head over to the
 | 
					
						
							|  |  |  | :ref:`installation` section.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A Minimal Application
 | 
					
						
							|  |  |  | ---------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-16 14:31:48 +08:00
										 |  |  | A minimal Flask application looks something like this::
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     from flask import Flask
 | 
					
						
							|  |  |  |     app = Flask(__name__)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @app.route('/')
 | 
					
						
							|  |  |  |     def hello_world():
 | 
					
						
							| 
									
										
										
										
											2015-01-16 17:36:17 +08:00
										 |  |  |         return 'Hello, World!'
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | So what did that code do?
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | 1. First we imported the :class:`~flask.Flask` class.  An instance of this
 | 
					
						
							| 
									
										
										
										
											2014-07-24 23:03:56 +08:00
										 |  |  |    class will be our WSGI application.
 | 
					
						
							| 
									
										
										
										
											2013-02-22 19:21:17 +08:00
										 |  |  | 2. Next we create an instance of this class. The first argument is the name of
 | 
					
						
							|  |  |  |    the application's module or package.  If you are using a single module (as
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  |    in this example), you should use ``__name__`` because depending on if it's
 | 
					
						
							| 
									
										
										
										
											2013-02-22 19:21:17 +08:00
										 |  |  |    started as application or imported as module the name will be different
 | 
					
						
							| 
									
										
										
										
											2013-02-22 23:33:20 +08:00
										 |  |  |    (``'__main__'`` versus the actual import name). This is needed so that
 | 
					
						
							|  |  |  |    Flask knows where to look for templates, static files, and so on. For more
 | 
					
						
							| 
									
										
										
										
											2013-02-22 23:34:16 +08:00
										 |  |  |    information have a look at the :class:`~flask.Flask` documentation.
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  | 3. We then use the :meth:`~flask.Flask.route` decorator to tell Flask what URL
 | 
					
						
							|  |  |  |    should trigger our function.
 | 
					
						
							|  |  |  | 4. The function is given a name which is also used to generate URLs for that
 | 
					
						
							|  |  |  |    particular function, and returns the message we want to display in the
 | 
					
						
							|  |  |  |    user's browser.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-29 21:46:48 +08:00
										 |  |  | Just save it as :file:`hello.py` or something similar. Make sure to not call
 | 
					
						
							|  |  |  | your application :file:`flask.py` because this would conflict with Flask
 | 
					
						
							|  |  |  | itself.
 | 
					
						
							| 
									
										
										
										
											2014-09-07 04:19:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-05 05:39:28 +08:00
										 |  |  | To run the application you can either use the :command:`flask` command or
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | python's ``-m`` switch with Flask.  Before you can do that you need
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  | to tell your terminal the application to work with by exporting the
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | ``FLASK_APP`` environment variable::
 | 
					
						
							| 
									
										
										
										
											2014-09-07 04:19:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  |     $ export FLASK_APP=hello.py
 | 
					
						
							|  |  |  |     $ flask run
 | 
					
						
							| 
									
										
										
										
											2014-09-07 04:19:57 +08:00
										 |  |  |      * Running on http://127.0.0.1:5000/
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | If you are on Windows you need to use ``set`` instead of ``export``.
 | 
					
						
							| 
									
										
										
										
											2014-09-07 04:19:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | Alternatively you can use :command:`python -m flask`::
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     $ export FLASK_APP=hello.py
 | 
					
						
							|  |  |  |     $ python -m flask run
 | 
					
						
							| 
									
										
										
										
											2014-09-07 04:19:57 +08:00
										 |  |  |      * Running on http://127.0.0.1:5000/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This launches a very simple builtin server, which is good enough for testing
 | 
					
						
							|  |  |  | but probably not what you want to use in production. For deployment options see
 | 
					
						
							|  |  |  | :ref:`deployment`.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Now head over to `http://127.0.0.1:5000/ <http://127.0.0.1:5000/>`_, and you
 | 
					
						
							| 
									
										
										
										
											2014-12-05 05:39:28 +08:00
										 |  |  | should see your hello world greeting.
 | 
					
						
							| 
									
										
										
										
											2010-04-11 08:58:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-24 23:46:06 +08:00
										 |  |  | .. _public-server:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. admonition:: Externally Visible Server
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  |    If you run the server you will notice that the server is only accessible
 | 
					
						
							| 
									
										
										
										
											2010-04-24 23:46:06 +08:00
										 |  |  |    from your own computer, not from any other in the network.  This is the
 | 
					
						
							|  |  |  |    default because in debugging mode a user of the application can execute
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  |    arbitrary Python code on your computer.
 | 
					
						
							| 
									
										
										
										
											2010-04-24 23:46:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:27:13 +08:00
										 |  |  |    If you have the debugger disabled or trust the users on your network,
 | 
					
						
							|  |  |  |    you can make the server publicly available simply by adding
 | 
					
						
							|  |  |  |    ``--host=0.0.0.0`` to the command line::
 | 
					
						
							| 
									
										
										
										
											2010-04-24 23:46:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  |        flask run --host=0.0.0.0
 | 
					
						
							| 
									
										
										
										
											2010-04-24 23:46:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  |    This tells your operating system to listen on all public IPs.
 | 
					
						
							| 
									
										
										
										
											2010-04-24 23:46:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-07 04:19:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:27:13 +08:00
										 |  |  | What to do if the Server does not Start
 | 
					
						
							|  |  |  | ---------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | In case the :command:`python -m flask` fails or :command:`flask` does not exist,
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:27:13 +08:00
										 |  |  | there are multiple reasons this might be the case.  First of all you need
 | 
					
						
							|  |  |  | to look at the error message.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Old Version of Flask
 | 
					
						
							|  |  |  | ````````````````````
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  | Versions of Flask older than 0.11 use to have different ways to start the
 | 
					
						
							| 
									
										
										
										
											2014-11-05 12:03:55 +08:00
										 |  |  | application.  In short, the :command:`flask` command did not exist, and
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | neither did :command:`python -m flask`.  In that case you have two options:
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:27:13 +08:00
										 |  |  | either upgrade to newer Flask versions or have a look at the :ref:`server`
 | 
					
						
							|  |  |  | docs to see the alternative method for running a server.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Invalid Import Name
 | 
					
						
							|  |  |  | ```````````````````
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | The ``-a`` argument to :command:`flask` is the name of the module to
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  | import.  In case that module is incorrectly named you will get an import
 | 
					
						
							|  |  |  | error upon start (or if debug is enabled when you navigate to the
 | 
					
						
							|  |  |  | application).  It will tell you what it tried to import and why it failed.
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:27:13 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | The most common reason is a typo or because you did not actually create an
 | 
					
						
							|  |  |  | ``app`` object.
 | 
					
						
							| 
									
										
										
										
											2010-04-11 08:58:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-04 07:11:14 +08:00
										 |  |  | .. _debug-mode:
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 08:58:13 +08:00
										 |  |  | Debug Mode
 | 
					
						
							|  |  |  | ----------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-06 12:25:41 +08:00
										 |  |  | (Want to just log errors and stack traces? See :ref:`application-errors`)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-05 12:03:55 +08:00
										 |  |  | The :command:`flask` script is nice to start a local development server, but
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:27:13 +08:00
										 |  |  | you would have to restart it manually after each change to your code.
 | 
					
						
							|  |  |  | That is not very nice and Flask can do better.  If you enable debug
 | 
					
						
							|  |  |  | support the server will reload itself on code changes, and it will also
 | 
					
						
							|  |  |  | provide you with a helpful debugger if things go wrong.
 | 
					
						
							| 
									
										
										
										
											2010-04-11 08:58:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | To enable debug mode you can export the ``FLASK_DEBUG`` environment variable
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  | before running the server::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $ export FLASK_DEBUG=1
 | 
					
						
							|  |  |  |     $ flask run
 | 
					
						
							| 
									
										
										
										
											2010-04-11 08:58:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | (On Windows you need to use ``set`` instead of ``export``).
 | 
					
						
							| 
									
										
										
										
											2010-04-11 08:58:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:27:13 +08:00
										 |  |  | This does the following things:
 | 
					
						
							| 
									
										
										
										
											2010-04-11 08:58:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:27:13 +08:00
										 |  |  | 1.  it activates the debugger
 | 
					
						
							|  |  |  | 2.  it activates the automatic reloader
 | 
					
						
							|  |  |  | 3.  it enables the debug mode on the Flask application.
 | 
					
						
							| 
									
										
										
										
											2010-04-11 08:58:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:27:13 +08:00
										 |  |  | There are more parameters that are explained in the :ref:`server` docs.
 | 
					
						
							| 
									
										
										
										
											2010-04-11 08:58:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-16 08:03:45 +08:00
										 |  |  | .. admonition:: Attention
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  |    Even though the interactive debugger does not work in forking environments
 | 
					
						
							|  |  |  |    (which makes it nearly impossible to use on production servers), it still
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  |    allows the execution of arbitrary code. This makes it a major security risk
 | 
					
						
							|  |  |  |    and therefore it **must never be used on production machines**.
 | 
					
						
							| 
									
										
										
										
											2010-04-16 08:03:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-16 08:14:54 +08:00
										 |  |  | Screenshot of the debugger in action:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. image:: _static/debugger.png
 | 
					
						
							|  |  |  |    :align: center
 | 
					
						
							|  |  |  |    :class: screenshot
 | 
					
						
							|  |  |  |    :alt: screenshot of debugger in action
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-04 07:11:14 +08:00
										 |  |  | Have another debugger in mind? See :ref:`working-with-debuggers`.
 | 
					
						
							| 
									
										
										
										
											2011-05-13 00:54:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | Routing
 | 
					
						
							|  |  |  | -------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | Modern web applications have beautiful URLs.  This helps people remember
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  | the URLs, which is especially handy for applications that are used from
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | mobile devices with slower network connections.  If the user can directly
 | 
					
						
							|  |  |  | go to the desired page without having to hit the index page it is more
 | 
					
						
							| 
									
										
										
										
											2011-06-28 20:34:07 +08:00
										 |  |  | likely they will like the page and come back next time.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  | As you have seen above, the :meth:`~flask.Flask.route` decorator is used to
 | 
					
						
							|  |  |  | bind a function to a URL.  Here are some basic examples::
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @app.route('/')
 | 
					
						
							|  |  |  |     def index():
 | 
					
						
							|  |  |  |         return 'Index Page'
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @app.route('/hello')
 | 
					
						
							|  |  |  |     def hello():
 | 
					
						
							| 
									
										
										
										
											2015-01-16 17:36:17 +08:00
										 |  |  |         return 'Hello, World'
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  | But there is more to it!  You can make certain parts of the URL dynamic and
 | 
					
						
							|  |  |  | attach multiple rules to a function.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | Variable Rules
 | 
					
						
							|  |  |  | ``````````````
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | To add variable parts to a URL you can mark these special sections as
 | 
					
						
							| 
									
										
										
										
											2013-03-27 05:23:55 +08:00
										 |  |  | ``<variable_name>``.  Such a part is then passed as a keyword argument to your
 | 
					
						
							|  |  |  | function.  Optionally a converter can be used by specifying a rule with
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  | ``<converter:variable_name>``.  Here are some nice examples::
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @app.route('/user/<username>')
 | 
					
						
							|  |  |  |     def show_user_profile(username):
 | 
					
						
							|  |  |  |         # show the user profile for that user
 | 
					
						
							| 
									
										
										
										
											2011-12-28 02:08:44 +08:00
										 |  |  |         return 'User %s' % username
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @app.route('/post/<int:post_id>')
 | 
					
						
							|  |  |  |     def show_post(post_id):
 | 
					
						
							|  |  |  |         # show the post with the given id, the id is an integer
 | 
					
						
							| 
									
										
										
										
											2011-12-28 02:08:44 +08:00
										 |  |  |         return 'Post %d' % post_id
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | The following converters exist:
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-20 06:22:37 +08:00
										 |  |  | =========== ===============================================
 | 
					
						
							|  |  |  | `string`    accepts any text without a slash (the default)
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | `int`       accepts integers
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | `float`     like ``int`` but for floating point values
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | `path`      like the default but also accepts slashes
 | 
					
						
							| 
									
										
										
										
											2016-04-02 05:05:11 +08:00
										 |  |  | `any`       matches one of the items provided
 | 
					
						
							|  |  |  | `uuid`      accepts UUID strings
 | 
					
						
							| 
									
										
										
										
											2014-09-20 06:22:37 +08:00
										 |  |  | =========== ===============================================
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-19 23:51:38 +08:00
										 |  |  | .. admonition:: Unique URLs / Redirection Behavior
 | 
					
						
							| 
									
										
										
										
											2010-05-24 21:24:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-27 04:43:50 +08:00
										 |  |  |    Flask's URL rules are based on Werkzeug's routing module.  The idea
 | 
					
						
							|  |  |  |    behind that module is to ensure beautiful and unique URLs based on
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  |    precedents laid down by Apache and earlier HTTP servers.
 | 
					
						
							| 
									
										
										
										
											2010-05-24 21:24:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |    Take these two rules::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @app.route('/projects/')
 | 
					
						
							|  |  |  |         def projects():
 | 
					
						
							| 
									
										
										
										
											2011-12-28 02:08:44 +08:00
										 |  |  |             return 'The project page'
 | 
					
						
							| 
									
										
										
										
											2010-05-24 21:24:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         @app.route('/about')
 | 
					
						
							|  |  |  |         def about():
 | 
					
						
							| 
									
										
										
										
											2011-12-28 02:08:44 +08:00
										 |  |  |             return 'The about page'
 | 
					
						
							| 
									
										
										
										
											2010-05-24 21:24:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  |    Though they look rather similar, they differ in their use of the trailing
 | 
					
						
							|  |  |  |    slash in the URL *definition*.  In the first case, the canonical URL for the
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  |    ``projects`` endpoint has a trailing slash.  In that sense, it is similar to
 | 
					
						
							| 
									
										
										
										
											2014-10-27 18:33:45 +08:00
										 |  |  |    a folder on a filesystem.  Accessing it without a trailing slash will cause
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  |    Flask to redirect to the canonical URL with the trailing slash.
 | 
					
						
							| 
									
										
										
										
											2010-05-24 21:24:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  |    In the second case, however, the URL is defined without a trailing slash,
 | 
					
						
							|  |  |  |    rather like the pathname of a file on UNIX-like systems. Accessing the URL
 | 
					
						
							|  |  |  |    with a trailing slash will produce a 404 "Not Found" error.
 | 
					
						
							| 
									
										
										
										
											2010-05-24 21:24:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-27 05:23:55 +08:00
										 |  |  |    This behavior allows relative URLs to continue working even if the trailing
 | 
					
						
							| 
									
										
										
										
											2013-09-04 01:47:00 +08:00
										 |  |  |    slash is omitted, consistent with how Apache and other servers work.  Also,
 | 
					
						
							|  |  |  |    the URLs will stay unique, which helps search engines avoid indexing the
 | 
					
						
							| 
									
										
										
										
											2013-03-27 05:23:55 +08:00
										 |  |  |    same page twice.
 | 
					
						
							| 
									
										
										
										
											2010-05-24 21:24:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-02 17:36:42 +08:00
										 |  |  | .. _url-building:
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | URL Building
 | 
					
						
							|  |  |  | ````````````
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  | If it can match URLs, can Flask also generate them?  Of course it can.  To
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | build a URL to a specific function you can use the :func:`~flask.url_for`
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  | function.  It accepts the name of the function as first argument and a number
 | 
					
						
							|  |  |  | of keyword arguments, each corresponding to the variable part of the URL rule.
 | 
					
						
							|  |  |  | Unknown variable parts are appended to the URL as query parameters.  Here are
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | some examples::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> from flask import Flask, url_for
 | 
					
						
							|  |  |  |     >>> app = Flask(__name__)
 | 
					
						
							|  |  |  |     >>> @app.route('/')
 | 
					
						
							|  |  |  |     ... def index(): pass
 | 
					
						
							|  |  |  |     ...
 | 
					
						
							|  |  |  |     >>> @app.route('/login')
 | 
					
						
							|  |  |  |     ... def login(): pass
 | 
					
						
							|  |  |  |     ...
 | 
					
						
							|  |  |  |     >>> @app.route('/user/<username>')
 | 
					
						
							|  |  |  |     ... def profile(username): pass
 | 
					
						
							|  |  |  |     ...
 | 
					
						
							|  |  |  |     >>> with app.test_request_context():
 | 
					
						
							|  |  |  |     ...  print url_for('index')
 | 
					
						
							|  |  |  |     ...  print url_for('login')
 | 
					
						
							|  |  |  |     ...  print url_for('login', next='/')
 | 
					
						
							|  |  |  |     ...  print url_for('profile', username='John Doe')
 | 
					
						
							|  |  |  |     ...
 | 
					
						
							|  |  |  |     /
 | 
					
						
							|  |  |  |     /login
 | 
					
						
							|  |  |  |     /login?next=/
 | 
					
						
							|  |  |  |     /user/John%20Doe
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  | (This also uses the :meth:`~flask.Flask.test_request_context` method, explained
 | 
					
						
							|  |  |  | below.  It tells Flask to behave as though it is handling a request, even
 | 
					
						
							| 
									
										
										
										
											2012-02-27 04:43:50 +08:00
										 |  |  | though we are interacting with it through a Python shell.  Have a look at the
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  | explanation below. :ref:`context-locals`).
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:27:13 +08:00
										 |  |  | Why would you want to build URLs using the URL reversing function
 | 
					
						
							|  |  |  | :func:`~flask.url_for` instead of hard-coding them into your templates?
 | 
					
						
							|  |  |  | There are three good reasons for this:
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:16:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  | 1. Reversing is often more descriptive than hard-coding the URLs.  More
 | 
					
						
							|  |  |  |    importantly, it allows you to change URLs in one go, without having to
 | 
					
						
							|  |  |  |    remember to change URLs all over the place.
 | 
					
						
							| 
									
										
										
										
											2010-05-30 02:06:12 +08:00
										 |  |  | 2. URL building will handle escaping of special characters and Unicode
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  |    data transparently for you, so you don't have to deal with them.
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | 3. If your application is placed outside the URL root - say, in
 | 
					
						
							|  |  |  |    ``/myapplication`` instead of ``/`` - :func:`~flask.url_for` will handle
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  |    that properly for you.
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:16:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | HTTP Methods
 | 
					
						
							|  |  |  | ````````````
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-26 10:55:01 +08:00
										 |  |  | HTTP (the protocol web applications are speaking) knows different methods for
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:13:01 +08:00
										 |  |  | accessing URLs.  By default, a route only answers to ``GET`` requests, but that
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | can be changed by providing the ``methods`` argument to the
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | :meth:`~flask.Flask.route` decorator.  Here are some examples::
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-03 09:15:27 +08:00
										 |  |  |     from flask import request
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  |     @app.route('/login', methods=['GET', 'POST'])
 | 
					
						
							|  |  |  |     def login():
 | 
					
						
							|  |  |  |         if request.method == 'POST':
 | 
					
						
							|  |  |  |             do_the_login()
 | 
					
						
							|  |  |  |         else:
 | 
					
						
							|  |  |  |             show_the_login_form()
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:13:01 +08:00
										 |  |  | If ``GET`` is present, ``HEAD`` will be added automatically for you.  You
 | 
					
						
							|  |  |  | don't have to deal with that.  It will also make sure that ``HEAD`` requests
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  | are handled as the `HTTP RFC`_ (the document describing the HTTP
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:22:26 +08:00
										 |  |  | protocol) demands, so you can completely ignore that part of the HTTP
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:13:01 +08:00
										 |  |  | specification.  Likewise, as of Flask 0.6, ``OPTIONS`` is implemented for you
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  | automatically as well.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | You have no idea what an HTTP method is?  Worry not, here is a quick
 | 
					
						
							|  |  |  | introduction to HTTP methods and why they matter:
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:16:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | The HTTP method (also often called "the verb") tells the server what the
 | 
					
						
							| 
									
										
										
										
											2016-04-02 05:12:25 +08:00
										 |  |  | client wants to *do* with the requested page.  The following methods are
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:16:42 +08:00
										 |  |  | very common:
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:13:01 +08:00
										 |  |  | ``GET``
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  |     The browser tells the server to just *get* the information stored on
 | 
					
						
							|  |  |  |     that page and send it.  This is probably the most common method.
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:16:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:13:01 +08:00
										 |  |  | ``HEAD``
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  |     The browser tells the server to get the information, but it is only
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:16:42 +08:00
										 |  |  |     interested in the *headers*, not the content of the page.  An
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:13:01 +08:00
										 |  |  |     application is supposed to handle that as if a ``GET`` request was
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  |     received but to not deliver the actual content.  In Flask you don't
 | 
					
						
							|  |  |  |     have to deal with that at all, the underlying Werkzeug library handles
 | 
					
						
							|  |  |  |     that for you.
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:16:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:13:01 +08:00
										 |  |  | ``POST``
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:16:42 +08:00
										 |  |  |     The browser tells the server that it wants to *post* some new
 | 
					
						
							|  |  |  |     information to that URL and that the server must ensure the data is
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  |     stored and only stored once.  This is how HTML forms usually
 | 
					
						
							|  |  |  |     transmit data to the server.
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:16:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:13:01 +08:00
										 |  |  | ``PUT``
 | 
					
						
							|  |  |  |     Similar to ``POST`` but the server might trigger the store procedure
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:16:42 +08:00
										 |  |  |     multiple times by overwriting the old values more than once.  Now you
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  |     might be asking why this is useful, but there are some good reasons
 | 
					
						
							|  |  |  |     to do it this way.  Consider that the connection is lost during
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  |     transmission: in this situation a system between the browser and the
 | 
					
						
							|  |  |  |     server might receive the request safely a second time without breaking
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:13:01 +08:00
										 |  |  |     things.  With ``POST`` that would not be possible because it must only
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:16:42 +08:00
										 |  |  |     be triggered once.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:13:01 +08:00
										 |  |  | ``DELETE``
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  |     Remove the information at the given location.
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:16:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:13:01 +08:00
										 |  |  | ``OPTIONS``
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  |     Provides a quick way for a client to figure out which methods are
 | 
					
						
							|  |  |  |     supported by this URL.  Starting with Flask 0.6, this is implemented
 | 
					
						
							|  |  |  |     for you automatically.
 | 
					
						
							| 
									
										
										
										
											2010-07-13 05:04:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:16:42 +08:00
										 |  |  | Now the interesting part is that in HTML4 and XHTML1, the only methods a
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:13:01 +08:00
										 |  |  | form can submit to the server are ``GET`` and ``POST``.  But with JavaScript
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | and future HTML standards you can use the other methods as well.  Furthermore
 | 
					
						
							|  |  |  | HTTP has become quite popular lately and browsers are no longer the only
 | 
					
						
							| 
									
										
										
										
											2013-07-01 00:17:39 +08:00
										 |  |  | clients that are using HTTP. For instance, many revision control systems
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | use it.
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:16:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:22:26 +08:00
										 |  |  | .. _HTTP RFC: http://www.ietf.org/rfc/rfc2068.txt
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 19:40:05 +08:00
										 |  |  | Static Files
 | 
					
						
							|  |  |  | ------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  | Dynamic web applications also need static files.  That's usually where
 | 
					
						
							| 
									
										
										
										
											2010-04-09 19:40:05 +08:00
										 |  |  | the CSS and JavaScript files are coming from.  Ideally your web server is
 | 
					
						
							|  |  |  | configured to serve them for you, but during development Flask can do that
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:45:22 +08:00
										 |  |  | as well.  Just create a folder called :file:`static` in your package or next to
 | 
					
						
							| 
									
										
										
										
											2014-11-05 12:19:02 +08:00
										 |  |  | your module and it will be available at ``/static`` on the application.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 19:40:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-04 08:55:58 +08:00
										 |  |  | To generate URLs for static files, use the special ``'static'`` endpoint name::
 | 
					
						
							| 
									
										
										
										
											2010-04-09 19:40:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     url_for('static', filename='style.css')
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:45:22 +08:00
										 |  |  | The file has to be stored on the filesystem as :file:`static/style.css`.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 19:40:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | Rendering Templates
 | 
					
						
							|  |  |  | -------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Generating HTML from within Python is not fun, and actually pretty
 | 
					
						
							|  |  |  | cumbersome because you have to do the HTML escaping on your own to keep
 | 
					
						
							|  |  |  | the application secure.  Because of that Flask configures the `Jinja2
 | 
					
						
							| 
									
										
										
										
											2014-04-26 07:20:12 +08:00
										 |  |  | <http://jinja.pocoo.org/>`_ template engine for you automatically.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | To render a template you can use the :func:`~flask.render_template`
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  | method.  All you have to do is provide the name of the template and the
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | variables you want to pass to the template engine as keyword arguments.
 | 
					
						
							| 
									
										
										
										
											2010-04-22 03:10:57 +08:00
										 |  |  | Here's a simple example of how to render a template::
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     from flask import render_template
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @app.route('/hello/')
 | 
					
						
							|  |  |  |     @app.route('/hello/<name>')
 | 
					
						
							|  |  |  |     def hello(name=None):
 | 
					
						
							|  |  |  |         return render_template('hello.html', name=name)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:45:22 +08:00
										 |  |  | Flask will look for templates in the :file:`templates` folder.  So if your
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  | application is a module, this folder is next to that module, if it's a
 | 
					
						
							| 
									
										
										
										
											2010-05-12 09:18:42 +08:00
										 |  |  | package it's actually inside your package:
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | **Case 1**: a module::
 | 
					
						
							| 
									
										
										
										
											2010-05-30 02:06:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  |     /application.py
 | 
					
						
							|  |  |  |     /templates
 | 
					
						
							|  |  |  |         /hello.html
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | **Case 2**: a package::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /application
 | 
					
						
							|  |  |  |         /__init__.py
 | 
					
						
							|  |  |  |         /templates
 | 
					
						
							|  |  |  |             /hello.html
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For templates you can use the full power of Jinja2 templates.  Head over
 | 
					
						
							| 
									
										
										
										
											2012-07-21 19:55:45 +08:00
										 |  |  | to the official `Jinja2 Template Documentation
 | 
					
						
							| 
									
										
										
										
											2014-04-26 07:20:12 +08:00
										 |  |  | <http://jinja.pocoo.org/docs/templates>`_ for more information.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | Here is an example template:
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | .. sourcecode:: html+jinja
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <!doctype html>
 | 
					
						
							|  |  |  |     <title>Hello from Flask</title>
 | 
					
						
							|  |  |  |     {% if name %}
 | 
					
						
							|  |  |  |       <h1>Hello {{ name }}!</h1>
 | 
					
						
							|  |  |  |     {% else %}
 | 
					
						
							| 
									
										
										
										
											2015-01-16 17:36:17 +08:00
										 |  |  |       <h1>Hello, World!</h1>
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  |     {% endif %}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Inside templates you also have access to the :class:`~flask.request`,
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:41:01 +08:00
										 |  |  | :class:`~flask.session` and :class:`~flask.g` [#]_ objects
 | 
					
						
							|  |  |  | as well as the :func:`~flask.get_flashed_messages` function.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 19:40:05 +08:00
										 |  |  | Templates are especially useful if inheritance is used.  If you want to
 | 
					
						
							|  |  |  | know how that works, head over to the :ref:`template-inheritance` pattern
 | 
					
						
							|  |  |  | documentation.  Basically template inheritance makes it possible to keep
 | 
					
						
							|  |  |  | certain elements on each page (like header, navigation and footer).
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | Automatic escaping is enabled, so if ``name`` contains HTML it will be escaped
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | automatically.  If you can trust a variable and you know that it will be
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  | safe HTML (for example because it came from a module that converts wiki
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | markup to HTML) you can mark it as safe by using the
 | 
					
						
							|  |  |  | :class:`~jinja2.Markup` class or by using the ``|safe`` filter in the
 | 
					
						
							|  |  |  | template.  Head over to the Jinja 2 documentation for more examples.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | Here is a basic introduction to how the :class:`~jinja2.Markup` class works::
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  |     >>> from flask import Markup
 | 
					
						
							|  |  |  |     >>> Markup('<strong>Hello %s!</strong>') % '<blink>hacker</blink>'
 | 
					
						
							|  |  |  |     Markup(u'<strong>Hello <blink>hacker</blink>!</strong>')
 | 
					
						
							|  |  |  |     >>> Markup.escape('<blink>hacker</blink>')
 | 
					
						
							|  |  |  |     Markup(u'<blink>hacker</blink>')
 | 
					
						
							|  |  |  |     >>> Markup('<em>Marked up</em> » HTML').striptags()
 | 
					
						
							|  |  |  |     u'Marked up \xbb HTML'
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-04 17:16:24 +08:00
										 |  |  | .. versionchanged:: 0.5
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Autoescaping is no longer enabled for all templates.  The following
 | 
					
						
							|  |  |  |    extensions for templates trigger autoescaping: ``.html``, ``.htm``,
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  |    ``.xml``, ``.xhtml``.  Templates loaded from a string will have
 | 
					
						
							| 
									
										
										
										
											2010-07-04 17:16:24 +08:00
										 |  |  |    autoescaping disabled.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | .. [#] Unsure what that :class:`~flask.g` object is? It's something in which
 | 
					
						
							|  |  |  |    you can store information for your own needs, check the documentation of
 | 
					
						
							|  |  |  |    that object (:class:`~flask.g`) and the :ref:`sqlite3` for more
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:41:01 +08:00
										 |  |  |    information.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | Accessing Request Data
 | 
					
						
							|  |  |  | ----------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-31 01:10:13 +08:00
										 |  |  | For web applications it's crucial to react to the data a client sends to
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | the server.  In Flask this information is provided by the global
 | 
					
						
							|  |  |  | :class:`~flask.request` object.  If you have some experience with Python
 | 
					
						
							|  |  |  | you might be wondering how that object can be global and how Flask
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  | manages to still be threadsafe.  The answer is context locals:
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | .. _context-locals:
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | Context Locals
 | 
					
						
							|  |  |  | ``````````````
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. admonition:: Insider Information
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    If you want to understand how that works and how you can implement
 | 
					
						
							|  |  |  |    tests with context locals, read this section, otherwise just skip it.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | Certain objects in Flask are global objects, but not of the usual kind.
 | 
					
						
							|  |  |  | These objects are actually proxies to objects that are local to a specific
 | 
					
						
							|  |  |  | context.  What a mouthful.  But that is actually quite easy to understand.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | Imagine the context being the handling thread.  A request comes in and the
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  | web server decides to spawn a new thread (or something else, the
 | 
					
						
							|  |  |  | underlying object is capable of dealing with concurrency systems other
 | 
					
						
							|  |  |  | than threads).  When Flask starts its internal request handling it
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | figures out that the current thread is the active context and binds the
 | 
					
						
							|  |  |  | current application and the WSGI environments to that context (thread).
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  | It does that in an intelligent way so that one application can invoke another
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | application without breaking.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | So what does this mean to you?  Basically you can completely ignore that
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  | this is the case unless you are doing something like unit testing.  You
 | 
					
						
							|  |  |  | will notice that code which depends on a request object will suddenly break
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | because there is no request object.  The solution is creating a request
 | 
					
						
							|  |  |  | object yourself and binding it to the context.  The easiest solution for
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  | unit testing is to use the :meth:`~flask.Flask.test_request_context`
 | 
					
						
							| 
									
										
										
										
											2014-11-05 12:39:54 +08:00
										 |  |  | context manager.  In combination with the ``with`` statement it will bind a
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | test request so that you can interact with it.  Here is an example::
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     from flask import request
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with app.test_request_context('/hello', method='POST'):
 | 
					
						
							|  |  |  |         # now you can do something with the request until the
 | 
					
						
							|  |  |  |         # end of the with block, such as basic assertions:
 | 
					
						
							|  |  |  |         assert request.path == '/hello'
 | 
					
						
							|  |  |  |         assert request.method == 'POST'
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The other possibility is passing a whole WSGI environment to the
 | 
					
						
							|  |  |  | :meth:`~flask.Flask.request_context` method::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     from flask import request
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with app.request_context(environ):
 | 
					
						
							|  |  |  |         assert request.method == 'POST'
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The Request Object
 | 
					
						
							|  |  |  | ``````````````````
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The request object is documented in the API section and we will not cover
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | it here in detail (see :class:`~flask.request`). Here is a broad overview of
 | 
					
						
							|  |  |  | some of the most common operations.  First of all you have to import it from
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | the ``flask`` module::
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     from flask import request
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The current request method is available by using the
 | 
					
						
							|  |  |  | :attr:`~flask.request.method` attribute.  To access form data (data
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:13:01 +08:00
										 |  |  | transmitted in a ``POST`` or ``PUT`` request) you can use the
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | :attr:`~flask.request.form` attribute.  Here is a full example of the two
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | attributes mentioned above::
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-02 17:32:14 +08:00
										 |  |  |     @app.route('/login', methods=['POST', 'GET'])
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  |     def login():
 | 
					
						
							|  |  |  |         error = None
 | 
					
						
							|  |  |  |         if request.method == 'POST':
 | 
					
						
							|  |  |  |             if valid_login(request.form['username'],
 | 
					
						
							|  |  |  |                            request.form['password']):
 | 
					
						
							|  |  |  |                 return log_the_user_in(request.form['username'])
 | 
					
						
							|  |  |  |             else:
 | 
					
						
							|  |  |  |                 error = 'Invalid username/password'
 | 
					
						
							| 
									
										
										
										
											2013-03-15 22:31:00 +08:00
										 |  |  |         # the code below is executed if the request method
 | 
					
						
							| 
									
										
										
										
											2012-06-26 01:31:11 +08:00
										 |  |  |         # was GET or the credentials were invalid
 | 
					
						
							|  |  |  |         return render_template('login.html', error=error)
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | What happens if the key does not exist in the ``form`` attribute?  In that
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | case a special :exc:`KeyError` is raised.  You can catch it like a
 | 
					
						
							|  |  |  | standard :exc:`KeyError` but if you don't do that, a HTTP 400 Bad Request
 | 
					
						
							|  |  |  | error page is shown instead.  So for many situations you don't have to
 | 
					
						
							|  |  |  | deal with that problem.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | To access parameters submitted in the URL (``?key=value``) you can use the
 | 
					
						
							|  |  |  | :attr:`~flask.request.args` attribute::
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-23 05:32:48 +08:00
										 |  |  |     searchword = request.args.get('key', '')
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | We recommend accessing URL parameters with `get` or by catching the
 | 
					
						
							| 
									
										
										
										
											2014-11-05 13:16:27 +08:00
										 |  |  | :exc:`KeyError` because users might change the URL and presenting them a 400
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | bad request page in that case is not user friendly.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | For a full list of methods and attributes of the request object, head over
 | 
					
						
							|  |  |  | to the :class:`~flask.request` documentation.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | File Uploads
 | 
					
						
							|  |  |  | ````````````
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | You can handle uploaded files with Flask easily.  Just make sure not to
 | 
					
						
							|  |  |  | forget to set the ``enctype="multipart/form-data"`` attribute on your HTML
 | 
					
						
							|  |  |  | form, otherwise the browser will not transmit your files at all.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | Uploaded files are stored in memory or at a temporary location on the
 | 
					
						
							|  |  |  | filesystem.  You can access those files by looking at the
 | 
					
						
							|  |  |  | :attr:`~flask.request.files` attribute on the request object.  Each
 | 
					
						
							|  |  |  | uploaded file is stored in that dictionary.  It behaves just like a
 | 
					
						
							|  |  |  | standard Python :class:`file` object, but it also has a
 | 
					
						
							| 
									
										
										
										
											2011-03-14 08:47:57 +08:00
										 |  |  | :meth:`~werkzeug.datastructures.FileStorage.save` method that allows you to store that
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | file on the filesystem of the server.  Here is a simple example showing how
 | 
					
						
							|  |  |  | that works::
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     from flask import request
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @app.route('/upload', methods=['GET', 'POST'])
 | 
					
						
							|  |  |  |     def upload_file():
 | 
					
						
							|  |  |  |         if request.method == 'POST':
 | 
					
						
							|  |  |  |             f = request.files['the_file']
 | 
					
						
							|  |  |  |             f.save('/var/www/uploads/uploaded_file.txt')
 | 
					
						
							|  |  |  |         ...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you want to know how the file was named on the client before it was
 | 
					
						
							|  |  |  | uploaded to your application, you can access the
 | 
					
						
							| 
									
										
										
										
											2011-03-14 08:47:57 +08:00
										 |  |  | :attr:`~werkzeug.datastructures.FileStorage.filename` attribute.  However please keep in
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | mind that this value can be forged so never ever trust that value.  If you
 | 
					
						
							|  |  |  | want to use the filename of the client to store the file on the server,
 | 
					
						
							| 
									
										
										
										
											2011-03-14 08:47:57 +08:00
										 |  |  | pass it through the :func:`~werkzeug.utils.secure_filename` function that
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | Werkzeug provides for you::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     from flask import request
 | 
					
						
							| 
									
										
										
										
											2015-05-15 14:44:49 +08:00
										 |  |  |     from werkzeug.utils import secure_filename
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @app.route('/upload', methods=['GET', 'POST'])
 | 
					
						
							|  |  |  |     def upload_file():
 | 
					
						
							|  |  |  |         if request.method == 'POST':
 | 
					
						
							| 
									
										
										
										
											2010-06-07 16:27:44 +08:00
										 |  |  |             f = request.files['the_file']
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  |             f.save('/var/www/uploads/' + secure_filename(f.filename))
 | 
					
						
							|  |  |  |         ...
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-18 04:46:35 +08:00
										 |  |  | For some better examples, checkout the :ref:`uploading-files` pattern.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | Cookies
 | 
					
						
							|  |  |  | ```````
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-07 21:23:57 +08:00
										 |  |  | To access cookies you can use the :attr:`~flask.Request.cookies`
 | 
					
						
							|  |  |  | attribute.  To set cookies you can use the
 | 
					
						
							|  |  |  | :attr:`~flask.Response.set_cookie` method of response objects.  The
 | 
					
						
							|  |  |  | :attr:`~flask.Request.cookies` attribute of request objects is a
 | 
					
						
							|  |  |  | dictionary with all the cookies the client transmits.  If you want to use
 | 
					
						
							|  |  |  | sessions, do not use the cookies directly but instead use the
 | 
					
						
							|  |  |  | :ref:`sessions` in Flask that add some security on top of cookies for you.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Reading cookies::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     from flask import request
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @app.route('/')
 | 
					
						
							|  |  |  |     def index():
 | 
					
						
							|  |  |  |         username = request.cookies.get('username')
 | 
					
						
							|  |  |  |         # use cookies.get(key) instead of cookies[key] to not get a
 | 
					
						
							|  |  |  |         # KeyError if the cookie is missing.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Storing cookies::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     from flask import make_response
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @app.route('/')
 | 
					
						
							|  |  |  |     def index():
 | 
					
						
							|  |  |  |         resp = make_response(render_template(...))
 | 
					
						
							|  |  |  |         resp.set_cookie('username', 'the username')
 | 
					
						
							|  |  |  |         return resp
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-21 00:03:37 +08:00
										 |  |  | Note that cookies are set on response objects.  Since you normally
 | 
					
						
							| 
									
										
										
										
											2011-08-07 21:23:57 +08:00
										 |  |  | just return strings from the view functions Flask will convert them into
 | 
					
						
							|  |  |  | response objects for you.  If you explicitly want to do that you can use
 | 
					
						
							|  |  |  | the :meth:`~flask.make_response` function and then modify it.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-06 00:51:47 +08:00
										 |  |  | Sometimes you might want to set a cookie at a point where the response
 | 
					
						
							|  |  |  | object does not exist yet.  This is possible by utilizing the
 | 
					
						
							|  |  |  | :ref:`deferred-callbacks` pattern.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-07 22:21:58 +08:00
										 |  |  | For this also see :ref:`about-responses`.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | Redirects and Errors
 | 
					
						
							|  |  |  | --------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-05 13:49:55 +08:00
										 |  |  | To redirect a user to another endpoint, use the :func:`~flask.redirect`
 | 
					
						
							|  |  |  | function; to abort a request early with an error code, use the
 | 
					
						
							|  |  |  | :func:`~flask.abort` function::
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     from flask import abort, redirect, url_for
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @app.route('/')
 | 
					
						
							|  |  |  |     def index():
 | 
					
						
							|  |  |  |         return redirect(url_for('login'))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @app.route('/login')
 | 
					
						
							|  |  |  |     def login():
 | 
					
						
							|  |  |  |         abort(401)
 | 
					
						
							|  |  |  |         this_is_never_executed()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This is a rather pointless example because a user will be redirected from
 | 
					
						
							| 
									
										
										
										
											2011-06-28 20:34:07 +08:00
										 |  |  | the index to a page they cannot access (401 means access denied) but it
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | shows how that works.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | By default a black and white error page is shown for each error code.  If
 | 
					
						
							|  |  |  | you want to customize the error page, you can use the
 | 
					
						
							|  |  |  | :meth:`~flask.Flask.errorhandler` decorator::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     from flask import render_template
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @app.errorhandler(404)
 | 
					
						
							|  |  |  |     def page_not_found(error):
 | 
					
						
							| 
									
										
										
										
											2010-04-11 09:53:38 +08:00
										 |  |  |         return render_template('page_not_found.html'), 404
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Note the ``404`` after the :func:`~flask.render_template` call.  This
 | 
					
						
							|  |  |  | tells Flask that the status code of that page should be 404 which means
 | 
					
						
							| 
									
										
										
										
											2010-05-12 09:18:42 +08:00
										 |  |  | not found.  By default 200 is assumed which translates to: all went well.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-11 22:57:17 +08:00
										 |  |  | See :ref:`error-handlers` for more details.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-07 22:21:58 +08:00
										 |  |  | .. _about-responses:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | About Responses
 | 
					
						
							|  |  |  | ---------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The return value from a view function is automatically converted into a
 | 
					
						
							|  |  |  | response object for you.  If the return value is a string it's converted
 | 
					
						
							| 
									
										
										
										
											2013-06-28 04:32:20 +08:00
										 |  |  | into a response object with the string as response body, a ``200 OK``
 | 
					
						
							| 
									
										
										
										
											2014-11-05 12:43:00 +08:00
										 |  |  | status code and a :mimetype:`text/html` mimetype.  The logic that Flask applies to
 | 
					
						
							| 
									
										
										
										
											2011-08-07 22:21:58 +08:00
										 |  |  | converting return values into response objects is as follows:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 1.  If a response object of the correct type is returned it's directly
 | 
					
						
							|  |  |  |     returned from the view.
 | 
					
						
							|  |  |  | 2.  If it's a string, a response object is created with that data and the
 | 
					
						
							|  |  |  |     default parameters.
 | 
					
						
							| 
									
										
										
										
											2012-04-09 22:56:33 +08:00
										 |  |  | 3.  If a tuple is returned the items in the tuple can provide extra
 | 
					
						
							|  |  |  |     information.  Such tuples have to be in the form ``(response, status,
 | 
					
						
							| 
									
										
										
										
											2014-01-01 05:16:13 +08:00
										 |  |  |     headers)`` or ``(response, headers)`` where at least one item has
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  |     to be in the tuple.  The ``status`` value will override the status code
 | 
					
						
							|  |  |  |     and ``headers`` can be a list or dictionary of additional header values.
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  | 4.  If none of that works, Flask will assume the return value is a
 | 
					
						
							|  |  |  |     valid WSGI application and convert that into a response object.
 | 
					
						
							| 
									
										
										
										
											2011-08-07 22:21:58 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | If you want to get hold of the resulting response object inside the view
 | 
					
						
							|  |  |  | you can use the :func:`~flask.make_response` function.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | Imagine you have a view like this::
 | 
					
						
							| 
									
										
										
										
											2011-08-07 22:21:58 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @app.errorhandler(404)
 | 
					
						
							|  |  |  |     def not_found(error):
 | 
					
						
							|  |  |  |         return render_template('error.html'), 404
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You just need to wrap the return expression with
 | 
					
						
							| 
									
										
										
										
											2013-02-18 00:04:20 +08:00
										 |  |  | :func:`~flask.make_response` and get the response object to modify it, then
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | return it::
 | 
					
						
							| 
									
										
										
										
											2011-08-07 22:21:58 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @app.errorhandler(404)
 | 
					
						
							|  |  |  |     def not_found(error):
 | 
					
						
							|  |  |  |         resp = make_response(render_template('error.html'), 404)
 | 
					
						
							|  |  |  |         resp.headers['X-Something'] = 'A value'
 | 
					
						
							|  |  |  |         return resp
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | .. _sessions:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Sessions
 | 
					
						
							|  |  |  | --------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  | In addition to the request object there is also a second object called
 | 
					
						
							|  |  |  | :class:`~flask.session` which allows you to store information specific to a
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | user from one request to the next.  This is implemented on top of cookies
 | 
					
						
							| 
									
										
										
										
											2010-05-12 09:18:42 +08:00
										 |  |  | for you and signs the cookies cryptographically.  What this means is that
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | the user could look at the contents of your cookie but not modify it,
 | 
					
						
							| 
									
										
										
										
											2011-06-28 20:34:07 +08:00
										 |  |  | unless they know the secret key used for signing.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | In order to use sessions you have to set a secret key.  Here is how
 | 
					
						
							|  |  |  | sessions work::
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-01 06:19:32 +08:00
										 |  |  |     from flask import Flask, session, redirect, url_for, escape, request
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     app = Flask(__name__)
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @app.route('/')
 | 
					
						
							|  |  |  |     def index():
 | 
					
						
							|  |  |  |         if 'username' in session:
 | 
					
						
							|  |  |  |             return 'Logged in as %s' % escape(session['username'])
 | 
					
						
							|  |  |  |         return 'You are not logged in'
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @app.route('/login', methods=['GET', 'POST'])
 | 
					
						
							|  |  |  |     def login():
 | 
					
						
							|  |  |  |         if request.method == 'POST':
 | 
					
						
							|  |  |  |             session['username'] = request.form['username']
 | 
					
						
							|  |  |  |             return redirect(url_for('index'))
 | 
					
						
							|  |  |  |         return '''
 | 
					
						
							| 
									
										
										
										
											2016-06-23 06:01:41 +08:00
										 |  |  |             <form method="post">
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  |                 <p><input type=text name=username>
 | 
					
						
							|  |  |  |                 <p><input type=submit value=Login>
 | 
					
						
							|  |  |  |             </form>
 | 
					
						
							|  |  |  |         '''
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @app.route('/logout')
 | 
					
						
							|  |  |  |     def logout():
 | 
					
						
							| 
									
										
										
										
											2012-04-11 04:14:38 +08:00
										 |  |  |         # remove the username from the session if it's there
 | 
					
						
							| 
									
										
										
										
											2010-04-09 07:32:39 +08:00
										 |  |  |         session.pop('username', None)
 | 
					
						
							| 
									
										
										
										
											2010-07-01 06:19:32 +08:00
										 |  |  |         return redirect(url_for('index'))
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-10 23:26:49 +08:00
										 |  |  |     # set the secret key.  keep this really secret:
 | 
					
						
							| 
									
										
										
										
											2010-05-25 05:07:09 +08:00
										 |  |  |     app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
 | 
					
						
							| 
									
										
										
										
											2010-04-10 23:26:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  | The :func:`~flask.escape` mentioned here does escaping for you if you are
 | 
					
						
							|  |  |  | not using the template engine (as in this example).
 | 
					
						
							| 
									
										
										
										
											2010-04-11 10:00:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | .. admonition:: How to generate good secret keys
 | 
					
						
							| 
									
										
										
										
											2010-05-26 21:19:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  |    The problem with random is that it's hard to judge what is truly random.  And
 | 
					
						
							| 
									
										
										
										
											2010-05-26 21:19:08 +08:00
										 |  |  |    a secret key should be as random as possible.  Your operating system
 | 
					
						
							| 
									
										
										
										
											2010-05-30 02:06:12 +08:00
										 |  |  |    has ways to generate pretty random stuff based on a cryptographic
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  |    random generator which can be used to get such a key::
 | 
					
						
							| 
									
										
										
										
											2010-05-26 21:19:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  |        >>> import os
 | 
					
						
							|  |  |  |        >>> os.urandom(24)
 | 
					
						
							|  |  |  |        '\xfd{H\xe5<\x95\xf9\xe3\x96.5\xd1\x01O<!\xd5\xa2\xa0\x9fR"\xa1\xa8'
 | 
					
						
							| 
									
										
										
										
											2010-05-26 21:19:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  |        Just take that thing and copy/paste it into your code and you're done.
 | 
					
						
							| 
									
										
										
										
											2010-05-26 21:19:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-04 02:19:04 +08:00
										 |  |  | A note on cookie-based sessions: Flask will take the values you put into the
 | 
					
						
							|  |  |  | session object and serialize them into a cookie.  If you are finding some
 | 
					
						
							|  |  |  | values do not persist across requests, cookies are indeed enabled, and you are
 | 
					
						
							|  |  |  | not getting a clear error message, check the size of the cookie in your page
 | 
					
						
							|  |  |  | responses compared to the size supported by web browsers.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-29 06:06:53 +08:00
										 |  |  | Besides the default client-side based sessions, if you want to handle
 | 
					
						
							|  |  |  | sessions on the server-side instead, there are several
 | 
					
						
							|  |  |  | Flask extensions that support this.
 | 
					
						
							| 
									
										
										
										
											2012-02-04 02:19:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | Message Flashing
 | 
					
						
							|  |  |  | ----------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Good applications and user interfaces are all about feedback.  If the user
 | 
					
						
							| 
									
										
										
										
											2011-06-28 20:34:07 +08:00
										 |  |  | does not get enough feedback they will probably end up hating the
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | application.  Flask provides a really simple way to give feedback to a
 | 
					
						
							|  |  |  | user with the flashing system.  The flashing system basically makes it
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  | possible to record a message at the end of a request and access it on the next
 | 
					
						
							|  |  |  | (and only the next) request.  This is usually combined with a layout
 | 
					
						
							|  |  |  | template to expose the message.
 | 
					
						
							| 
									
										
										
										
											2010-04-09 18:49:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-09 19:46:12 +08:00
										 |  |  | To flash a message use the :func:`~flask.flash` method, to get hold of the
 | 
					
						
							|  |  |  | messages you can use :func:`~flask.get_flashed_messages` which is also
 | 
					
						
							|  |  |  | available in the templates.  Check out the :ref:`message-flashing-pattern`
 | 
					
						
							|  |  |  | for a full example.
 | 
					
						
							| 
									
										
										
										
											2010-05-18 04:46:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | Logging
 | 
					
						
							|  |  |  | -------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-28 07:18:29 +08:00
										 |  |  | .. versionadded:: 0.3
 | 
					
						
							| 
									
										
										
										
											2010-05-18 04:46:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | Sometimes you might be in a situation where you deal with data that
 | 
					
						
							| 
									
										
										
										
											2011-12-24 17:55:52 +08:00
										 |  |  | should be correct, but actually is not.  For example you may have some client-side
 | 
					
						
							|  |  |  | code that sends an HTTP request to the server but it's obviously
 | 
					
						
							|  |  |  | malformed.  This might be caused by a user tampering with the data, or the
 | 
					
						
							|  |  |  | client code failing.  Most of the time it's okay to reply with ``400 Bad
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | Request`` in that situation, but sometimes that won't do and the code has
 | 
					
						
							|  |  |  | to continue working.
 | 
					
						
							| 
									
										
										
										
											2010-05-18 04:46:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | You may still want to log that something fishy happened.  This is where
 | 
					
						
							|  |  |  | loggers come in handy.  As of Flask 0.3 a logger is preconfigured for you
 | 
					
						
							|  |  |  | to use.
 | 
					
						
							| 
									
										
										
										
											2010-05-18 04:46:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | Here are some example log calls::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     app.logger.debug('A value for debugging')
 | 
					
						
							| 
									
										
										
										
											2010-05-30 02:06:12 +08:00
										 |  |  |     app.logger.warning('A warning occurred (%d apples)', 42)
 | 
					
						
							|  |  |  |     app.logger.error('An error occurred')
 | 
					
						
							| 
									
										
										
										
											2010-05-18 04:46:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | The attached :attr:`~flask.Flask.logger` is a standard logging
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | :class:`~logging.Logger`, so head over to the official `logging
 | 
					
						
							| 
									
										
										
										
											2014-04-26 07:36:36 +08:00
										 |  |  | documentation <https://docs.python.org/library/logging.html>`_ for more
 | 
					
						
							| 
									
										
										
										
											2010-07-28 07:10:31 +08:00
										 |  |  | information.
 | 
					
						
							| 
									
										
										
										
											2010-07-17 21:39:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-26 08:01:42 +08:00
										 |  |  | Read more on :ref:`application-errors`.
 | 
					
						
							| 
									
										
										
										
											2014-09-07 04:19:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-17 21:39:24 +08:00
										 |  |  | Hooking in WSGI Middlewares
 | 
					
						
							|  |  |  | ---------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you want to add a WSGI middleware to your application you can wrap the
 | 
					
						
							| 
									
										
										
										
											2010-07-17 22:02:21 +08:00
										 |  |  | internal WSGI application.  For example if you want to use one of the
 | 
					
						
							| 
									
										
										
										
											2010-07-17 21:39:24 +08:00
										 |  |  | middlewares from the Werkzeug package to work around bugs in lighttpd, you
 | 
					
						
							|  |  |  | can do it like this::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     from werkzeug.contrib.fixers import LighttpdCGIRootFix
 | 
					
						
							|  |  |  |     app.wsgi_app = LighttpdCGIRootFix(app.wsgi_app)
 | 
					
						
							| 
									
										
										
										
											2012-03-12 11:20:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-12 11:54:09 +08:00
										 |  |  | Using Flask Extensions
 | 
					
						
							|  |  |  | ----------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Extensions are packages that help you accomplish common tasks. For
 | 
					
						
							|  |  |  | example, Flask-SQLAlchemy provides SQLAlchemy support that makes it simple
 | 
					
						
							|  |  |  | and easy to use with Flask.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For more on Flask extensions, have a look at :ref:`extensions`.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-12 11:20:32 +08:00
										 |  |  | Deploying to a Web Server
 | 
					
						
							|  |  |  | -------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-07 04:19:57 +08:00
										 |  |  | Ready to deploy your new Flask app? Go to :ref:`deployment`.
 |