Merge branch 'master' of github.com:mitsuhiko/flask

This commit is contained in:
Armin Ronacher 2012-04-09 15:26:09 +01:00
commit 3249eeb438
32 changed files with 626 additions and 259 deletions

View file

@ -0,0 +1,67 @@
Foreword for Experienced Programmers
====================================
This chapter is for programmers who have worked with other frameworks in the
past, and who may have more specific or esoteric concerns that the typical
user.
Threads in Flask
----------------
One of the design decisions with Flask was that simple tasks should be simple;
they should not take a lot of code and yet they should not limit you. Because
of that we made a few design choices that some people might find surprising or
unorthodox. For example, Flask uses thread-local objects internally so that
you dont have to pass objects around from function to function within a
request in order to stay threadsafe. While this is a really easy approach and
saves you a lot of time, it might also cause some troubles for very large
applications because changes on these thread-local objects can happen anywhere
in the same thread. In order to solve these problems we dont hide the thread
locals for you but instead embrace them and provide you with a lot of tools to
make it as pleasant as possible to work with them.
Web Development is Dangerous
----------------------------
If you write a web application, you are probably allowing users to register
and leave their data on your server. The users are entrusting you with data.
And even if you are the only user that might leave data in your application,
you still want that data to be stored securely.
Unfortunately, there are many ways the security of a web application can be
compromised. Flask protects you against one of the most common security
problems of modern web applications: cross-site scripting (XSS). Unless
you deliberately mark insecure HTML as secure, Flask and the underlying
Jinja2 template engine have you covered. But there are many more ways to
cause security problems.
The documentation will warn you about aspects of web development that
require attention to security. Some of these security concerns
are far more complex than one might think, and we all sometimes underestimate
the likelihood that a vulnerability will be exploited - until a clever
attacker figures out a way to exploit our applications. And don't think
that your application is not important enough to attract an attacker.
Depending on the kind of attack, chances are that automated bots are
probing for ways to fill your database with spam, links to malicious
software, and the like.
So always keep security in mind when doing web development.
The Status of Python 3
----------------------
Currently the Python community is in the process of improving libraries to
support the new iteration of the Python programming language. While the
situation is greatly improving there are still some issues that make it
hard for us to switch over to Python 3 just now. These problems are
partially caused by changes in the language that went unreviewed for too
long, partially also because we have not quite worked out how the lower-
level API should change to account for the Unicode differences in Python 3.
Werkzeug and Flask will be ported to Python 3 as soon as a solution for
the changes is found, and we will provide helpful tips how to upgrade
existing applications to Python 3. Until then, we strongly recommend
using Python 2.6 and 2.7 with activated Python 3 warnings during
development. If you plan on upgrading to Python 3 in the near future we
strongly recommend that you read `How to write forwards compatible
Python code <http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/>`_.

View file

@ -525,7 +525,7 @@ Variable parts are passed to the view function as keyword arguments.
The following converters are available:
=========== ===============================================
`unicode` accepts any text without a slash (the default)
`string` accepts any text without a slash (the default)
`int` accepts integers
`float` like `int` but for floating point values
`path` like the default but also accepts slashes

View file

@ -43,7 +43,7 @@ master_doc = 'index'
# General information about the project.
project = u'Flask'
copyright = u'2010, Armin Ronacher'
copyright = u'2012, Armin Ronacher'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the

View file

@ -110,6 +110,13 @@ The following configuration values are used internally by Flask:
reject incoming requests with a
content length greater than this by
returning a 413 status code.
``SEND_FILE_MAX_AGE_DEFAULT``: Default cache control max age to use with
:meth:`flask.Flask.send_static_file`, in
seconds. Override this value on a per-file
basis using the
:meth:`flask.Flask.get_send_file_options` and
:meth:`flask.Blueprint.get_send_file_options`
hooks. Defaults to 43200 (12 hours).
``TRAP_HTTP_EXCEPTIONS`` If this is set to ``True`` Flask will
not execute the error handlers of HTTP
exceptions but instead treat the
@ -276,7 +283,7 @@ configuration::
class ProductionConfig(Config):
DATABASE_URI = 'mysql://user@localhost/foo'
class DevelopmentConfig(Config):
DEBUG = True

View file

@ -3,12 +3,11 @@
FastCGI
=======
FastCGI is a deployment option on servers like `nginx`_, `lighttpd`_,
and `cherokee`_; see :ref:`deploying-uwsgi` and
:ref:`deploying-other-servers` for other options. To use your WSGI
application with any of them you will need a FastCGI server first. The
most popular one is `flup`_ which we will use for this guide. Make sure
to have it installed to follow along.
FastCGI is a deployment option on servers like `nginx`_, `lighttpd`_, and
`cherokee`_; see :ref:`deploying-uwsgi` and :ref:`deploying-wsgi-standalone`
for other options. To use your WSGI application with any of them you will need
a FastCGI server first. The most popular one is `flup`_ which we will use for
this guide. Make sure to have it installed to follow along.
.. admonition:: Watch Out

View file

@ -13,11 +13,14 @@ If you have a different WSGI server look up the server documentation
about how to use a WSGI app with it. Just remember that your
:class:`Flask` application object is the actual WSGI application.
For hosted options to get up and running quickly, see
:ref:`quickstart_deployment` in the Quickstart.
.. toctree::
:maxdepth: 2
mod_wsgi
cgi
fastcgi
wsgi-standalone
uwsgi
others
fastcgi
cgi

View file

@ -4,11 +4,10 @@ uWSGI
=====
uWSGI is a deployment option on servers like `nginx`_, `lighttpd`_, and
`cherokee`_; see :ref:`deploying-fastcgi` and
:ref:`deploying-other-servers` for other options. To use your WSGI
application with uWSGI protocol you will need a uWSGI server
first. uWSGI is both a protocol and an application server; the
application server can serve uWSGI, FastCGI, and HTTP protocols.
`cherokee`_; see :ref:`deploying-fastcgi` and :ref:`deploying-wsgi-standalone`
for other options. To use your WSGI application with uWSGI protocol you will
need a uWSGI server first. uWSGI is both a protocol and an application server;
the application server can serve uWSGI, FastCGI, and HTTP protocols.
The most popular uWSGI server is `uwsgi`_, which we will use for this
guide. Make sure to have it installed to follow along.

View file

@ -1,11 +1,31 @@
.. _deploying-other-servers:
.. _deploying-wsgi-standalone:
Other Servers
=============
Standalone WSGI Containers
==========================
There are popular servers written in Python that allow the execution of WSGI
applications as well. These servers stand alone when they run; you can proxy
to them from your web server.
There are popular servers written in Python that contain WSGI applications and
serve HTTP. These servers stand alone when they run; you can proxy to them
from your web server. Note the section on :ref:`deploying-proxy-setups` if you
run into issues.
Gunicorn
--------
`Gunicorn`_ 'Green Unicorn' is a WSGI HTTP Server for UNIX. It's a pre-fork
worker model ported from Ruby's Unicorn project. It supports both `eventlet`_
and `greenlet`_. Running a Flask application on this server is quite simple::
gunicorn myproject:app
`Gunicorn`_ provides many command-line options -- see ``gunicorn -h``.
For example, to run a Flask application with 4 worker processes (``-w
4``) binding to localhost port 4000 (``-b 127.0.0.1:4000``)::
gunicorn -w 4 -b 127.0.0.1:4000 myproject:app
.. _Gunicorn: http://gunicorn.org/
.. _eventlet: http://eventlet.net/
.. _greenlet: http://codespeak.net/py/0.9.2/greenlet.html
Tornado
--------
@ -14,7 +34,7 @@ Tornado
server and tools that power `FriendFeed`_. Because it is non-blocking and
uses epoll, it can handle thousands of simultaneous standing connections,
which means it is ideal for real-time web services. Integrating this
service with Flask is a trivial task::
service with Flask is straightforward::
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
@ -46,44 +66,54 @@ event loop::
.. _greenlet: http://codespeak.net/py/0.9.2/greenlet.html
.. _libevent: http://monkey.org/~provos/libevent/
Gunicorn
--------
`Gunicorn`_ 'Green Unicorn' is a WSGI HTTP Server for UNIX. It's a pre-fork
worker model ported from Ruby's Unicorn project. It supports both `eventlet`_
and `greenlet`_. Running a Flask application on this server is quite simple::
gunicorn myproject:app
`Gunicorn`_ provides many command-line options -- see ``gunicorn -h``.
For example, to run a Flask application with 4 worker processes (``-w
4``) binding to localhost port 4000 (``-b 127.0.0.1:4000``)::
gunicorn -w 4 -b 127.0.0.1:4000 myproject:app
.. _Gunicorn: http://gunicorn.org/
.. _eventlet: http://eventlet.net/
.. _greenlet: http://codespeak.net/py/0.9.2/greenlet.html
.. _deploying-proxy-setups:
Proxy Setups
------------
If you deploy your application using one of these servers behind an HTTP
proxy you will need to rewrite a few headers in order for the
application to work. The two problematic values in the WSGI environment
usually are `REMOTE_ADDR` and `HTTP_HOST`. Werkzeug ships a fixer that
will solve some common setups, but you might want to write your own WSGI
middleware for specific setups.
If you deploy your application using one of these servers behind an HTTP proxy
you will need to rewrite a few headers in order for the application to work.
The two problematic values in the WSGI environment usually are `REMOTE_ADDR`
and `HTTP_HOST`. You can configure your httpd to pass these headers, or you
can fix them in middleware. Werkzeug ships a fixer that will solve some common
setups, but you might want to write your own WSGI middleware for specific
setups.
The most common setup invokes the host being set from `X-Forwarded-Host`
and the remote address from `X-Forwarded-For`::
Here's a simple nginx configuration which proxies to an application served on
localhost at port 8000, setting appropriate headers:
.. sourcecode:: nginx
server {
listen 80;
server_name _;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://127.0.0.1:8000/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
If your httpd is not providing these headers, the most common setup invokes the
host being set from `X-Forwarded-Host` and the remote address from
`X-Forwarded-For`::
from werkzeug.contrib.fixers import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app)
Please keep in mind that it is a security issue to use such a middleware
in a non-proxy setup because it will blindly trust the incoming
headers which might be forged by malicious clients.
.. admonition:: Trusting Headers
Please keep in mind that it is a security issue to use such a middleware in
a non-proxy setup because it will blindly trust the incoming headers which
might be forged by malicious clients.
If you want to rewrite the headers from another header, you might want to
use a fixer like this::

View file

@ -125,9 +125,8 @@ Initializing Extensions
-----------------------
Many extensions will need some kind of initialization step. For example,
consider your application is currently connecting to SQLite like the
documentation suggests (:ref:`sqlite3`) you will need to provide a few
functions and before / after request handlers. So how does the extension
consider an application that's currently connecting to SQLite like the
documentation suggests (:ref:`sqlite3`). So how does the extension
know the name of the application object?
Quite simple: you pass it to it.
@ -135,12 +134,14 @@ Quite simple: you pass it to it.
There are two recommended ways for an extension to initialize:
initialization functions:
If your extension is called `helloworld` you might have a function
called ``init_helloworld(app[, extra_args])`` that initializes the
extension for that application. It could attach before / after
handlers etc.
classes:
Classes work mostly like initialization functions but can later be
used to further change the behaviour. For an example look at how the
`OAuth extension`_ works: there is an `OAuth` object that provides
@ -148,92 +149,18 @@ classes:
a remote application that uses OAuth.
What to use depends on what you have in mind. For the SQLite 3 extension
we will use the class-based approach because it will provide users with a
manager object that handles opening and closing database connections.
we will use the class-based approach because it will provide users with an
object that handles opening and closing database connections.
The Extension Code
------------------
Here's the contents of the `flask_sqlite3.py` for copy/paste::
from __future__ import absolute_import
import sqlite3
from flask import _request_ctx_stack
class SQLite3(object):
def __init__(self, app):
self.app = app
self.app.config.setdefault('SQLITE3_DATABASE', ':memory:')
self.app.teardown_request(self.teardown_request)
self.app.before_request(self.before_request)
def connect(self):
return sqlite3.connect(self.app.config['SQLITE3_DATABASE'])
def before_request(self):
ctx = _request_ctx_stack.top
ctx.sqlite3_db = self.connect()
def teardown_request(self, exception):
ctx = _request_ctx_stack.top
ctx.sqlite3_db.close()
def get_db(self):
ctx = _request_ctx_stack.top
if ctx is not None:
return ctx.sqlite3_db
So here's what these lines of code do:
1. The ``__future__`` import is necessary to activate absolute imports.
Otherwise we could not call our module `sqlite3.py` and import the
top-level `sqlite3` module which actually implements the connection to
SQLite.
2. We create a class for our extension that requires a supplied `app` object,
sets a configuration for the database if it's not there
(:meth:`dict.setdefault`), and attaches `before_request` and
`teardown_request` handlers.
3. Next, we define a `connect` function that opens a database connection.
4. Then we set up the request handlers we bound to the app above. Note here
that we're attaching our database connection to the top request context via
`_request_ctx_stack.top`. Extensions should use the top context and not the
`g` object to store things like database connections.
5. Finally, we add a `get_db` function that simplifies access to the context's
database.
So why did we decide on a class-based approach here? Because using our
extension looks something like this::
from flask import Flask
from flask_sqlite3 import SQLite3
app = Flask(__name__)
app.config.from_pyfile('the-config.cfg')
manager = SQLite3(app)
db = manager.get_db()
You can then use the database from views like this::
@app.route('/')
def show_all():
cur = db.cursor()
cur.execute(...)
Opening a database connection from outside a view function is simple.
>>> from yourapplication import db
>>> cur = db.cursor()
>>> cur.execute(...)
Adding an `init_app` Function
-----------------------------
In practice, you'll almost always want to permit users to initialize your
extension and provide an app object after the fact. This can help avoid
circular import problems when a user is breaking their app into multiple files.
Our extension could add an `init_app` function as follows::
class SQLite3(object):
@ -251,7 +178,7 @@ Our extension could add an `init_app` function as follows::
self.app.before_request(self.before_request)
def connect(self):
return sqlite3.connect(app.config['SQLITE3_DATABASE'])
return sqlite3.connect(self.app.config['SQLITE3_DATABASE'])
def before_request(self):
ctx = _request_ctx_stack.top
@ -261,18 +188,69 @@ Our extension could add an `init_app` function as follows::
ctx = _request_ctx_stack.top
ctx.sqlite3_db.close()
def get_db(self):
@property
def connection(self):
ctx = _request_ctx_stack.top
if ctx is not None:
return ctx.sqlite3_db
The user could then initialize the extension in one file::
manager = SQLite3()
So here's what these lines of code do:
and bind their app to the extension in another file::
1. The ``__init__`` method takes an optional app object and, if supplied, will
call ``init_app``.
2. The ``init_app`` method exists so that the ``SQLite3`` object can be
instantiated without requiring an app object. This method supports the
factory pattern for creating applications. The ``init_app`` will set the
configuration for the database, defaulting to an in memory database if
no configuration is supplied. In addition, the ``init_app`` method attaches
``before_request`` and ``teardown_request`` handlers.
3. Next, we define a ``connect`` method that opens a database connection.
4. Then we set up the request handlers we bound to the app above. Note here
that we're attaching our database connection to the top request context via
``_request_ctx_stack.top``. Extensions should use the top context and not the
``g`` object to store things like database connections.
5. Finally, we add a ``connection`` property that simplifies access to the context's
database.
manager.init_app(app)
So why did we decide on a class-based approach here? Because using our
extension looks something like this::
from flask import Flask
from flask_sqlite3 import SQLite3
app = Flask(__name__)
app.config.from_pyfile('the-config.cfg')
db = SQLite3(app)
You can then use the database from views like this::
@app.route('/')
def show_all():
cur = db.connection.cursor()
cur.execute(...)
Additionally, the ``init_app`` method is used to support the factory pattern
for creating apps::
db = Sqlite3()
# Then later on.
app = create_app('the-config.cfg')
db.init_app(app)
Keep in mind that supporting this factory pattern for creating apps is required
for approved flask extensions (described below).
Using _request_ctx_stack
------------------------
In the example above, before every request, a ``sqlite3_db`` variable is assigned
to ``_request_ctx_stack.top``. In a view function, this variable is accessible
using the ``connection`` property of ``SQLite3``. During the teardown of a
request, the ``sqlite3_db`` connection is closed. By using this pattern, the
*same* connection to the sqlite3 database is accessible to anything that needs it
for the duration of the request.
End-Of-Request Behavior
-----------------------
@ -292,6 +270,7 @@ pattern is a good way to support both::
else:
app.after_request(close_connection)
Strictly speaking the above code is wrong, because teardown functions are
passed the exception and typically don't return anything. However because
the return value is discarded this will just work assuming that the code
@ -326,15 +305,19 @@ new releases. These approved extensions are listed on the `Flask
Extension Registry`_ and marked appropriately. If you want your own
extension to be approved you have to follow these guidelines:
0. An approved Flask extension requires a maintainer. In the event an
extension author would like to move beyond the project, the project should
find a new maintainer including full source hosting transition and PyPI
access. If no maintainer is available, give access to the Flask core team.
1. An approved Flask extension must provide exactly one package or module
named ``flask_extensionname``. They might also reside inside a
``flaskext`` namespace packages though this is discouraged now.
2. It must ship a testing suite that can either be invoked with ``make test``
or ``python setup.py test``. For test suites invoked with ``make
test`` the extension has to ensure that all dependencies for the test
are installed automatically, in case of ``python setup.py test``
dependencies for tests alone can be specified in the `setup.py`
file. The test suite also has to be part of the distribution.
are installed automatically. If tests are invoked with ``python setup.py
test``, test dependencies can be specified in the `setup.py` file. The
test suite also has to be part of the distribution.
3. APIs of approved extensions will be checked for the following
characteristics:

View file

@ -8,93 +8,48 @@ should or should not be using it.
What does "micro" mean?
-----------------------
To me, the "micro" in microframework refers not only to the simplicity and
small size of the framework, but also the fact that it does not make many
decisions for you. While Flask does pick a templating engine for you, we
won't make such decisions for your datastore or other parts.
“Micro” does not mean that your whole web application has to fit into
a single Python file (although it certainly can). Nor does it mean
that Flask is lacking in functionality. The "micro" in microframework
means Flask aims to keep the core simple but extensible. Flask won't make
many decisions for you, such as what database to use. Those decisions that
it does make, such as what templating engine to use, are easy to change.
Everything else is up to you, so that Flask can be everything you need
and nothing you don't.
However, to us the term “micro” does not mean that the whole implementation
has to fit into a single Python file.
By default, Flask does not include a database abstraction layer, form
validation or anything else where different libraries already exist that can
handle that. Instead, FLask extensions add such functionality to your
application as if it was implemented in Flask itself. Numerous extensions
provide database integration, form validation, upload handling, various open
authentication technologies, and more. Flask may be "micro", but the
possibilities are endless.
One of the design decisions with Flask was that simple tasks should be
simple; they should not take a lot of code and yet they should not limit you.
Because of that we made a few design choices that some people might find
surprising or unorthodox. For example, Flask uses thread-local objects
internally so that you don't have to pass objects around from function to
function within a request in order to stay threadsafe. While this is a
really easy approach and saves you a lot of time, it might also cause some
troubles for very large applications because changes on these thread-local
objects can happen anywhere in the same thread. In order to solve these
problems we don't hide the thread locals for you but instead embrace them
and provide you with a lot of tools to make it as pleasant as possible to
work with them.
Convention over Configuration
-----------------------------
Flask is also based on convention over configuration, which means that
many things are preconfigured. For example, by convention templates and
static files are stored in subdirectories within the application's Python source tree.
While this can be changed you usually don't have to.
Flask is based on convention over configuration, which means that many things
are preconfigured. For example, by convention templates and static files are
stored in subdirectories within the application's Python source tree. While
this can be changed you usually don't have to. We want to minimize the time
you need to spend in order to get up and running, without assuming things
about your needs.
The main reason Flask is called a "microframework" is the idea
to keep the core simple but extensible. There is no database abstraction
layer, no form validation or anything else where different libraries
already exist that can handle that. However Flask supports
extensions to add such functionality to your application as if it
was implemented in Flask itself. There are currently extensions for
object-relational mappers, form validation, upload handling, various open
authentication technologies and more.
Growing Up
----------
Since Flask is based on a very solid foundation there is not a lot of code
in Flask itself. As such it's easy to adapt even for large applications
and we are making sure that you can either configure it as much as
possible by subclassing things or by forking the entire codebase. If you
are interested in that, check out the :ref:`becomingbig` chapter.
Since Flask is based on a very solid foundation there is not a lot of code in
Flask itself. As such it's easy to adapt even for large applications and we
are making sure that you can either configure it as much as possible by
subclassing things or by forking the entire codebase. If you are interested
in that, check out the :ref:`becomingbig` chapter.
If you are curious about the Flask design principles, head over to the
section about :ref:`design`.
If you are curious about the Flask design principles, head over to the section
about :ref:`design`.
Web Development is Dangerous
----------------------------
For the Stalwart and Wizened...
-------------------------------
I'm not joking. Well, maybe a little. If you write a web
application, you are probably allowing users to register and leave their
data on your server. The users are entrusting you with data. And even if
you are the only user that might leave data in your application, you still
want that data to be stored securely.
Unfortunately, there are many ways the security of a web application can be
compromised. Flask protects you against one of the most common security
problems of modern web applications: cross-site scripting (XSS). Unless
you deliberately mark insecure HTML as secure, Flask and the underlying
Jinja2 template engine have you covered. But there are many more ways to
cause security problems.
The documentation will warn you about aspects of web development that
require attention to security. Some of these security concerns
are far more complex than one might think, and we all sometimes underestimate
the likelihood that a vulnerability will be exploited - until a clever
attacker figures out a way to exploit our applications. And don't think
that your application is not important enough to attract an attacker.
Depending on the kind of attack, chances are that automated bots are
probing for ways to fill your database with spam, links to malicious
software, and the like.
So always keep security in mind when doing web development.
The Status of Python 3
----------------------
Currently the Python community is in the process of improving libraries to
support the new iteration of the Python programming language. While the
situation is greatly improving there are still some issues that make it
hard for us to switch over to Python 3 just now. These problems are
partially caused by changes in the language that went unreviewed for too
long, partially also because we have not quite worked out how the lower-
level API should change to account for the Unicode differences in Python 3.
Werkzeug and Flask will be ported to Python 3 as soon as a solution for
the changes is found, and we will provide helpful tips how to upgrade
existing applications to Python 3. Until then, we strongly recommend
using Python 2.6 and 2.7 with activated Python 3 warnings during
development. If you plan on upgrading to Python 3 in the near future we
strongly recommend that you read `How to write forwards compatible
Python code <http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/>`_.
If you're more curious about the minutiae of Flask's implementation, and
whether its structure is right for your needs, read the
:ref:`advanced_foreword`.

View file

@ -94,7 +94,7 @@ System-Wide Installation
------------------------
This is possible as well, though I do not recommend it. Just run
`easy_install` with root privileges::
`pip` with root privileges::
$ sudo pip install Flask

View file

@ -30,6 +30,24 @@ at :func:`werkzeug.serving.run_simple`::
Note that :func:`run_simple <werkzeug.serving.run_simple>` is not intended for
use in production. Use a :ref:`full-blown WSGI server <deployment>`.
In order to use the interactive debuggger, debugging must be enabled both on
the application and the simple server, here is the "hello world" example with
debugging and :func:`run_simple <werkzeug.serving.run_simple>`::
from flask import Flask
from werkzeug.serving import run_simple
app = Flask(__name__)
app.debug = True
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
run_simple('localhost', 5000, app,
use_reloader=True, use_debugger=True, use_evalex=True)
Combining Applications
----------------------

View file

@ -141,4 +141,4 @@ These results are also dict-like objects:
u'admin@localhost'
For more information about MongoKit, head over to the
`website <http://bytebucket.org/namlook/mongokit/>`_.
`website <https://github.com/namlook/mongokit>`_.

View file

@ -55,7 +55,7 @@ following quick checklist:
`__init__.py` file. That way each module can import it safely and the
`__name__` variable will resolve to the correct package.
2. all the view functions (the ones with a :meth:`~flask.Flask.route`
decorator on top) have to be imported when in the `__init__.py` file.
decorator on top) have to be imported in the `__init__.py` file.
Not the object itself, but the module it is in. Import the view module
**after the application object is created**.

View file

@ -168,8 +168,8 @@ The following converters exist:
.. admonition:: Unique URLs / Redirection Behaviour
Flask's URL rules are based on Werkzeug's routing module. The idea behind
that module is to ensure beautiful and unique also unique URLs based on
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
precedents laid down by Apache and earlier HTTP servers.
Take these two rules::
@ -193,7 +193,7 @@ The following converters exist:
with a trailing slash will produce a 404 "Not Found" error.
This behavior allows relative URLs to continue working if users access the
page when they forget a trailing slash, consistent with how with how Apache
page when they forget a trailing slash, consistent with how Apache
and other servers work. Also, the URLs will stay unique, which helps search
engines avoid indexing the same page twice.
@ -234,7 +234,7 @@ some examples:
(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
though were are interacting with it through a Python shell. Have a look at the
though we are interacting with it through a Python shell. Have a look at the
explanation below. :ref:`context-locals`).
Why would you want to build URLs instead of hard-coding them into your
@ -333,8 +333,7 @@ configured to serve them for you, but during development Flask can do that
as well. Just create a folder called `static` in your package or next to
your module and it will be available at `/static` on the application.
To generate URLs that part of the URL, use the special ``'static'`` URL
name::
To generate URLs for static files, use the special ``'static'`` endpoint name::
url_for('static', filename='style.css')
@ -826,3 +825,26 @@ can do it like this::
from werkzeug.contrib.fixers import LighttpdCGIRootFix
app.wsgi_app = LighttpdCGIRootFix(app.wsgi_app)
.. _quickstart_deployment:
Deploying to a Web Server
-------------------------
Ready to deploy your new Flask app? To wrap up the quickstart, you can
immediately deploy to a hosted platform, all of which offer a free plan for
small projects:
- `Deploying Flask on Heroku <http://devcenter.heroku.com/articles/python>`_
- `Deploying Flask on ep.io <https://www.ep.io/docs/quickstart/flask/>`_
- `Deploying WSGI on dotCloud <http://docs.dotcloud.com/services/python/>`_
with `Flask-specific notes <http://flask.pocoo.org/snippets/48/>`_
Other places where you can host your Flask app:
- `Deploying Flask on Webfaction <http://flask.pocoo.org/snippets/65/>`_
- `Deploying Flask on Google App Engine <https://github.com/kamalgill/flask-appengine-template>`_
- `Sharing your Localhost Server with Localtunnel <http://flask.pocoo.org/snippets/89/>`_
If you manage your own hosts and would like to host yourself, see the chapter
on :ref:`deployment`.

View file

@ -131,6 +131,8 @@ debugging. You can access the name of the signal with the
missing blinker installations, you can do so by using the
:class:`flask.signals.Namespace` class.
.. _signals-sending:
Sending Signals
---------------
@ -156,6 +158,17 @@ function, you can pass ``current_app._get_current_object()`` as sender.
that :data:`~flask.current_app` is a proxy and not the real application
object.
Signals and Flask's Request Context
-----------------------------------
Signals fully support :ref:`request-context` when receiving signals.
Context-local variables are consistently available between
:data:`~flask.request_started` and :data:`~flask.request_finished`, so you can
rely on :class:`flask.g` and others as needed. Note the limitations described
in :ref:`signals-sending` and the :data:`~flask.request_tearing_down` signal.
Decorator Based Signal Subscriptions
------------------------------------

View file

@ -11,7 +11,7 @@ into the module which we will be doing here. However a cleaner solution
would be to create a separate `.ini` or `.py` file and load that or import
the values from there.
::
In `flaskr.py`::
# all the imports
import sqlite3
@ -26,7 +26,7 @@ the values from there.
PASSWORD = 'default'
Next we can create our actual application and initialize it with the
config from the same file::
config from the same file, in `flaskr.py`::
# create our little application :)
app = Flask(__name__)
@ -37,21 +37,21 @@ string it will import it) and then look for all uppercase variables
defined there. In our case, the configuration we just wrote a few lines
of code above. You can also move that into a separate file.
It is also a good idea to be able to load a configuration from a
configurable file. This is what :meth:`~flask.Config.from_envvar` can
do::
Usually, it is a good idea to load a configuration from a configurable
file. This is what :meth:`~flask.Config.from_envvar` can do, replacing the
:meth:`~flask.Config.from_object` line above::
app.config.from_envvar('FLASKR_SETTINGS', silent=True)
That way someone can set an environment variable called
:envvar:`FLASKR_SETTINGS` to specify a config file to be loaded which will
then override the default values. The silent switch just tells Flask to
not complain if no such environment key is set.
:envvar:`FLASKR_SETTINGS` to specify a config file to be loaded which will then
override the default values. The silent switch just tells Flask to not complain
if no such environment key is set.
The `secret_key` is needed to keep the client-side sessions secure.
Choose that key wisely and as hard to guess and complex as possible. The
debug flag enables or disables the interactive debugger. Never leave
debug mode activated in a production system because it will allow users to
debug flag enables or disables the interactive debugger. *Never leave
debug mode activated in a production system*, because it will allow users to
execute code on the server!
We also add a method to easily connect to the database specified. That