|
|
@ -3,9 +3,9 @@ |
|
|
|
Quickstart |
|
|
|
Quickstart |
|
|
|
========== |
|
|
|
========== |
|
|
|
|
|
|
|
|
|
|
|
Eager to get started? This page gives a good introduction on how to get |
|
|
|
Eager to get started? This page gives a good introduction to Flask. It |
|
|
|
started with Flask. This assumes you already have Flask installed. If |
|
|
|
assumes you already have Flask installed. If you do not, head over to the |
|
|
|
you do not, head over to the :ref:`installation` section. |
|
|
|
:ref:`installation` section. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A Minimal Application |
|
|
|
A Minimal Application |
|
|
@ -23,39 +23,39 @@ A minimal Flask application looks something like this:: |
|
|
|
if __name__ == '__main__': |
|
|
|
if __name__ == '__main__': |
|
|
|
app.run() |
|
|
|
app.run() |
|
|
|
|
|
|
|
|
|
|
|
Just save it as `hello.py` or something similar and run it with your |
|
|
|
Just save it as `hello.py` (or something similar) and run it with your Python |
|
|
|
Python interpreter. Make sure to not call your application `flask.py` |
|
|
|
interpreter. Make sure to not call your application `flask.py` because this |
|
|
|
because this would conflict with Flask itself. |
|
|
|
would conflict with Flask itself. |
|
|
|
|
|
|
|
|
|
|
|
:: |
|
|
|
:: |
|
|
|
|
|
|
|
|
|
|
|
$ python hello.py |
|
|
|
$ python hello.py |
|
|
|
* Running on http://127.0.0.1:5000/ |
|
|
|
* Running on http://127.0.0.1:5000/ |
|
|
|
|
|
|
|
|
|
|
|
Head over to `http://127.0.0.1:5000/ <http://127.0.0.1:5000/>`_, you should |
|
|
|
Now head over to `http://127.0.0.1:5000/ <http://127.0.0.1:5000/>`_, and you |
|
|
|
see your hello world greeting. |
|
|
|
should see your hello world greeting. |
|
|
|
|
|
|
|
|
|
|
|
So what did that code do? |
|
|
|
So what did that code do? |
|
|
|
|
|
|
|
|
|
|
|
1. First we imported the :class:`~flask.Flask` class. An instance of this |
|
|
|
1. First we imported the :class:`~flask.Flask` class. An instance of this |
|
|
|
class will be our WSGI application. The first argument is the name of |
|
|
|
class will be our WSGI application. The first argument is the name of |
|
|
|
the application's module. If you are using a single module (as in this example) |
|
|
|
the application's module. If you are using a single module (as in this |
|
|
|
you should use `__name__` because depending on whether it's started as |
|
|
|
example), you should use `__name__` because depending on if it's started as |
|
|
|
application or imported as module the name will be different |
|
|
|
application or imported as module the name will be different (``'__main__'`` |
|
|
|
(``'__main__'`` versus the actual import name). For more information |
|
|
|
versus the actual import name). For more information, have a look at the |
|
|
|
on this technique, have a look at the :class:`~flask.Flask` documentation. |
|
|
|
:class:`~flask.Flask` documentation. |
|
|
|
2. Next we create an instance of it. We pass it the name of the module / |
|
|
|
2. Next we create an instance of this class. We pass it the name of the module |
|
|
|
package. This is needed so that Flask knows where it should look for |
|
|
|
or package. This is needed so that Flask knows where to look for templates, |
|
|
|
templates, static files and so on. |
|
|
|
static files, and so on. |
|
|
|
3. Then we use the :meth:`~flask.Flask.route` decorator to tell Flask |
|
|
|
3. We then use the :meth:`~flask.Flask.route` decorator to tell Flask what URL |
|
|
|
which URL should trigger our function. |
|
|
|
should trigger our function. |
|
|
|
4. The function then has a name which is also used to generate URLs to |
|
|
|
4. The function is given a name which is also used to generate URLs for that |
|
|
|
that particular function, and returns the message we want to display in |
|
|
|
particular function, and returns the message we want to display in the |
|
|
|
the user's browser. |
|
|
|
user's browser. |
|
|
|
5. Finally we use the :meth:`~flask.Flask.run` function to run the |
|
|
|
5. Finally we use the :meth:`~flask.Flask.run` function to run the local server |
|
|
|
local server with our application. The ``if __name__ == '__main__':`` |
|
|
|
with our application. The ``if __name__ == '__main__':`` makes sure the |
|
|
|
makes sure the server only runs if the script is executed directly from |
|
|
|
server only runs if the script is executed directly from the Python |
|
|
|
the Python interpreter and not used as imported module. |
|
|
|
interpreter and not used as imported module. |
|
|
|
|
|
|
|
|
|
|
|
To stop the server, hit control-C. |
|
|
|
To stop the server, hit control-C. |
|
|
|
|
|
|
|
|
|
|
@ -74,7 +74,7 @@ To stop the server, hit control-C. |
|
|
|
|
|
|
|
|
|
|
|
app.run(host='0.0.0.0') |
|
|
|
app.run(host='0.0.0.0') |
|
|
|
|
|
|
|
|
|
|
|
This tells your operating system to listen on a public IP. |
|
|
|
This tells your operating system to listen on all public IPs. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Debug Mode |
|
|
|
Debug Mode |
|
|
@ -92,18 +92,18 @@ application object:: |
|
|
|
app.debug = True |
|
|
|
app.debug = True |
|
|
|
app.run() |
|
|
|
app.run() |
|
|
|
|
|
|
|
|
|
|
|
Or pass it to `run`:: |
|
|
|
Or pass it as a parameter to run:: |
|
|
|
|
|
|
|
|
|
|
|
app.run(debug=True) |
|
|
|
app.run(debug=True) |
|
|
|
|
|
|
|
|
|
|
|
Both will have exactly the same effect. |
|
|
|
Both methods have the exact same effect. |
|
|
|
|
|
|
|
|
|
|
|
.. admonition:: Attention |
|
|
|
.. admonition:: Attention |
|
|
|
|
|
|
|
|
|
|
|
Even though the interactive debugger does not work in forking environments |
|
|
|
Even though the interactive debugger does not work in forking environments |
|
|
|
(which makes it nearly impossible to use on production servers), it still |
|
|
|
(which makes it nearly impossible to use on production servers), it still |
|
|
|
allows the execution of arbitrary code. That makes it a major security |
|
|
|
allows the execution of arbitrary code. This makes it a major security risk |
|
|
|
risk and therefore it **must never be used on production machines**. |
|
|
|
and therefore it **must never be used on production machines**. |
|
|
|
|
|
|
|
|
|
|
|
Screenshot of the debugger in action: |
|
|
|
Screenshot of the debugger in action: |
|
|
|
|
|
|
|
|
|
|
@ -159,8 +159,8 @@ 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 |
|
|
|
go to the desired page without having to hit the index page it is more |
|
|
|
likely they will like the page and come back next time. |
|
|
|
likely they will like the page and come back next time. |
|
|
|
|
|
|
|
|
|
|
|
As you have seen above, the :meth:`~flask.Flask.route` decorator is used |
|
|
|
As you have seen above, the :meth:`~flask.Flask.route` decorator is used to |
|
|
|
to bind a function to a URL. Here are some basic examples:: |
|
|
|
bind a function to a URL. Here are some basic examples:: |
|
|
|
|
|
|
|
|
|
|
|
@app.route('/') |
|
|
|
@app.route('/') |
|
|
|
def index(): |
|
|
|
def index(): |
|
|
@ -170,16 +170,16 @@ to bind a function to a URL. Here are some basic examples:: |
|
|
|
def hello(): |
|
|
|
def hello(): |
|
|
|
return 'Hello World' |
|
|
|
return 'Hello World' |
|
|
|
|
|
|
|
|
|
|
|
But there is more to it! You can make certain parts of the URL dynamic |
|
|
|
But there is more to it! You can make certain parts of the URL dynamic and |
|
|
|
and attach multiple rules to a function. |
|
|
|
attach multiple rules to a function. |
|
|
|
|
|
|
|
|
|
|
|
Variable Rules |
|
|
|
Variable Rules |
|
|
|
`````````````` |
|
|
|
`````````````` |
|
|
|
|
|
|
|
|
|
|
|
To add variable parts to a URL you can mark these special sections as |
|
|
|
To add variable parts to a URL you can mark these special sections as |
|
|
|
``<variable_name>``. Such a part is then passed as keyword argument to |
|
|
|
``<variable_name>``. Such a part is then passed as keyword argument to your |
|
|
|
your function. Optionally a converter can be specified by specifying a |
|
|
|
function. Optionally a converter can be specified by specifying a rule with |
|
|
|
rule with ``<converter:variable_name>``. Here are some nice examples:: |
|
|
|
``<converter:variable_name>``. Here are some nice examples:: |
|
|
|
|
|
|
|
|
|
|
|
@app.route('/user/<username>') |
|
|
|
@app.route('/user/<username>') |
|
|
|
def show_user_profile(username): |
|
|
|
def show_user_profile(username): |
|
|
@ -201,9 +201,9 @@ The following converters exist: |
|
|
|
|
|
|
|
|
|
|
|
.. admonition:: Unique URLs / Redirection Behaviour |
|
|
|
.. admonition:: Unique URLs / Redirection Behaviour |
|
|
|
|
|
|
|
|
|
|
|
Flask's URL rules are based on Werkzeug's routing module. The idea |
|
|
|
Flask's URL rules are based on Werkzeug's routing module. The idea behind |
|
|
|
behind that module is to ensure nice-looking and also unique URLs based |
|
|
|
that module is to ensure beautiful and unique also unique URLs based on |
|
|
|
on behaviour coined by Apache and earlier servers. |
|
|
|
precedents laid down by Apache and earlier HTTP servers. |
|
|
|
|
|
|
|
|
|
|
|
Take these two rules:: |
|
|
|
Take these two rules:: |
|
|
|
|
|
|
|
|
|
|
@ -215,21 +215,20 @@ The following converters exist: |
|
|
|
def about(): |
|
|
|
def about(): |
|
|
|
return 'The about page' |
|
|
|
return 'The about page' |
|
|
|
|
|
|
|
|
|
|
|
They look rather similar, the difference is the trailing slash in the |
|
|
|
Though they look rather similar, they differ in their use of the trailing |
|
|
|
URL *definition*. In the first case, the canonical URL for the |
|
|
|
slash in the URL *definition*. In the first case, the canonical URL for the |
|
|
|
`projects` endpoint has a trailing slash. It's similar to a folder in |
|
|
|
`projects` endpoint has a trailing slash. In that sense, it is similar to |
|
|
|
that sense. Accessing it without a trailing slash will cause Flask to |
|
|
|
a folder on a file system. Accessing it without a trailing slash will cause |
|
|
|
redirect to the canonical URL with the trailing slash. |
|
|
|
Flask to redirect to the canonical URL with the trailing slash. |
|
|
|
|
|
|
|
|
|
|
|
However, in the second case the URL is defined without a slash so it |
|
|
|
In the second case, however, the URL is defined without a trailing slash, |
|
|
|
behaves similar to a file and accessing the URL with a trailing slash |
|
|
|
rather like the pathname of a file on UNIX-like systems. Accessing the URL |
|
|
|
will result in a 404 error. |
|
|
|
with a trailing slash will produce a 404 "Not Found" error. |
|
|
|
|
|
|
|
|
|
|
|
Why is this? This allows relative URLs to continue working if users |
|
|
|
This behavior allows relative URLs to continue working if users access the |
|
|
|
access the page when they forget a trailing slash. This behaviour is |
|
|
|
page when they forget a trailing slash, consistent with how with how Apache |
|
|
|
also consistent with how Apache and other servers work. Also, the URLs |
|
|
|
and other servers work. Also, the URLs will stay unique, which helps search |
|
|
|
will stay unique which ensures search engines do not index the same page |
|
|
|
engines avoid indexing the same page twice. |
|
|
|
twice. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. _url-building: |
|
|
|
.. _url-building: |
|
|
@ -237,12 +236,12 @@ The following converters exist: |
|
|
|
URL Building |
|
|
|
URL Building |
|
|
|
```````````` |
|
|
|
```````````` |
|
|
|
|
|
|
|
|
|
|
|
If it can match URLs, can it also generate them? Of course it can. To |
|
|
|
If it can match URLs, can Flask also generate them? Of course it can. To |
|
|
|
build a URL to a specific function you can use the :func:`~flask.url_for` |
|
|
|
build a URL to a specific function you can use the :func:`~flask.url_for` |
|
|
|
function. It accepts the name of the function as first argument and a |
|
|
|
function. It accepts the name of the function as first argument and a number |
|
|
|
number of keyword arguments, each corresponding to the variable part of |
|
|
|
of keyword arguments, each corresponding to the variable part of the URL rule. |
|
|
|
the URL rule. Unknown variable parts are appended to the URL as query |
|
|
|
Unknown variable parts are appended to the URL as query parameters. Here are |
|
|
|
parameter. Here are some examples: |
|
|
|
some examples: |
|
|
|
|
|
|
|
|
|
|
|
>>> from flask import Flask, url_for |
|
|
|
>>> from flask import Flask, url_for |
|
|
|
>>> app = Flask(__name__) |
|
|
|
>>> app = Flask(__name__) |
|
|
@ -266,30 +265,30 @@ parameter. Here are some examples: |
|
|
|
/login?next=/ |
|
|
|
/login?next=/ |
|
|
|
/user/John%20Doe |
|
|
|
/user/John%20Doe |
|
|
|
|
|
|
|
|
|
|
|
(This also uses the :meth:`~flask.Flask.test_request_context` method |
|
|
|
(This also uses the :meth:`~flask.Flask.test_request_context` method, explained |
|
|
|
explained below. It basically tells Flask to think we are handling a |
|
|
|
below. It tells Flask to behave as though it is handling a request, even |
|
|
|
request even though we are not, we are in an interactive Python shell. |
|
|
|
though were are interacting with it through a Python shell. Have a look at the |
|
|
|
Have a look at the explanation below: :ref:`context-locals`.) |
|
|
|
explanation below. :ref:`context-locals`). |
|
|
|
|
|
|
|
|
|
|
|
Why would you want to build URLs instead of hardcoding them in your |
|
|
|
Why would you want to build URLs instead of hard-coding them into your |
|
|
|
templates? There are three good reasons for this: |
|
|
|
templates? There are three good reasons for this: |
|
|
|
|
|
|
|
|
|
|
|
1. reversing is often more descriptive than hardcoding the URLs. Also and |
|
|
|
1. Reversing is often more descriptive than hard-coding the URLs. More |
|
|
|
more importantly you can change URLs in one go without having to change |
|
|
|
importantly, it allows you to change URLs in one go, without having to |
|
|
|
the URLs all over the place. |
|
|
|
remember to change URLs all over the place. |
|
|
|
2. URL building will handle escaping of special characters and Unicode |
|
|
|
2. URL building will handle escaping of special characters and Unicode |
|
|
|
data transparently for you, you don't have to deal with that. |
|
|
|
data transparently for you, so you don't have to deal with them. |
|
|
|
3. If your application is placed outside the URL root (so say in |
|
|
|
3. If your application is placed outside the URL root (say, in |
|
|
|
``/myapplication`` instead of ``/``), :func:`~flask.url_for` will |
|
|
|
``/myapplication`` instead of ``/``), :func:`~flask.url_for` will handle |
|
|
|
handle that properly for you. |
|
|
|
that properly for you. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HTTP Methods |
|
|
|
HTTP Methods |
|
|
|
```````````` |
|
|
|
```````````` |
|
|
|
|
|
|
|
|
|
|
|
HTTP (the protocol web applications are speaking) knows different methods |
|
|
|
HTTP (the protocol web applications are speaking) knows different methods for |
|
|
|
to access URLs. By default a route only answers to `GET` requests, but |
|
|
|
accessing URLs. By default, a route only answers to `GET` requests, but that |
|
|
|
that can be changed by providing the `methods` argument to the |
|
|
|
can be changed by providing the `methods` argument to the |
|
|
|
:meth:`~flask.Flask.route` decorator. Here are some examples:: |
|
|
|
:meth:`~flask.Flask.route` decorator. Here are some examples:: |
|
|
|
|
|
|
|
|
|
|
|
@app.route('/login', methods=['GET', 'POST']) |
|
|
|
@app.route('/login', methods=['GET', 'POST']) |
|
|
|