Skip to content

Commit

Permalink
Merge branch 'master' into fix-issue-220
Browse files Browse the repository at this point in the history
  • Loading branch information
jfinkels committed Apr 26, 2012
2 parents cf38eec + e78e2a1 commit 918e0aa
Show file tree
Hide file tree
Showing 12 changed files with 244 additions and 160 deletions.
19 changes: 11 additions & 8 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,21 @@ Relase date to be decided, codename to be chosen.
- View functions can now return a tuple with the first instance being an
instance of :class:`flask.Response`. This allows for returning
``jsonify(error="error msg"), 400`` from a view function.
- :class:`flask.Flask` now provides a `get_send_file_options` hook for
subclasses to override behavior of serving static files from Flask when using
:meth:`flask.Flask.send_static_file` based on keywords in
:func:`flask.helpers.send_file`. This hook is provided a filename, which for
example allows changing cache controls by file extension. The default
max-age for `send_static_file` can be configured through a new
``SEND_FILE_MAX_AGE_DEFAULT`` configuration variable, regardless of whether
the `get_send_file_options` hook is used.
- :class:`~flask.Flask` and :class:`~flask.Blueprint` now provide a
:meth:`~flask.Flask.get_send_file_max_age` hook for subclasses to override
behavior of serving static files from Flask when using
:meth:`flask.Flask.send_static_file` (used for the default static file
handler) and :func:`~flask.helpers.send_file`. This hook is provided a
filename, which for example allows changing cache controls by file extension.
The default max-age for `send_file` and static files can be configured
through a new ``SEND_FILE_MAX_AGE_DEFAULT`` configuration variable, which is
used in the default `get_send_file_max_age` implementation.
- Fixed an assumption in sessions implementation which could break message
flashing on sessions implementations which use external storage.
- Changed the behavior of tuple return values from functions. They are no
longer arguments to the response object, they now have a defined meaning.
- Added :attr:`flask.Flask.request_globals_class` to allow a specific class to
be used on creation of the :data:`~flask.g` instance of each request.

Version 0.8.1
-------------
Expand Down
65 changes: 33 additions & 32 deletions docs/advanced_foreword.rst
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
.. _advanced_foreword:

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
----------------
Thread-Locals in Flask
----------------------

One of the design decisions with Flask was that simple tasks should be simple;
One of the design decisions in 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.
of that, Flask has 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. This approach is convenient, but requires a valid
request context for dependency injection or when attempting to reuse code which
uses a value pegged to the request. The Flask project is honest about
thread-locals, does not hide them, and calls out in the code and documentation
where they are used.

Web Development is Dangerous
----------------------------
Develop for the Web with Caution
--------------------------------

Always keep security in mind when building web applications.

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.
Expand All @@ -30,22 +29,22 @@ 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.
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.
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.
Flask is no different from any other framework in that you the developer must
build with caution, watching for exploits when building to your requirements.

The Status of Python 3
----------------------
Expand All @@ -65,3 +64,5 @@ 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/>`_.

Continue to :ref:`installation` or the :ref:`quickstart`.
100 changes: 56 additions & 44 deletions docs/becomingbig.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,57 @@
Becoming Big
============

Your application is becoming more and more complex? If you suddenly
realize that Flask does things in a way that does not work out for your
application there are ways to deal with that.

Flask is powered by Werkzeug and Jinja2, two libraries that are in use at
a number of large websites out there and all Flask does is bring those
two together. Being a microframework Flask does not do much more than
combining existing libraries - there is not a lot of code involved.
What that means for large applications is that it's very easy to take the
code from Flask and put it into a new module within the applications and
expand on that.

Flask is designed to be extended and modified in a couple of different
ways:

- Flask extensions. For a lot of reusable functionality you can create
extensions. For extensions a number of hooks exist throughout Flask
with signals and callback functions.

- Subclassing. The majority of functionality can be changed by creating
a new subclass of the :class:`~flask.Flask` class and overriding
methods provided for this exact purpose.

- Forking. If nothing else works out you can just take the Flask
codebase at a given point and copy/paste it into your application
and change it. Flask is designed with that in mind and makes this
incredible easy. You just have to take the package and copy it
into your application's code and rename it (for example to
`framework`). Then you can start modifying the code in there.

Why consider Forking?
Here are your options when growing your codebase or scaling your application.

Read the Source.
----------------

Flask started in part to demonstrate how to build your own framework on top of
existing well-used tools Werkzeug (WSGI) and Jinja (templating), and as it
developed, it became useful to a wide audience. As you grow your codebase,
don't just use Flask -- understand it. Read the source. Flask's code is
written to be read; it's documentation published so you can use its internal
APIs. Flask sticks to documented APIs in upstream libraries, and documents its
internal utilities so that you can find the hook points needed for your
project.

Hook. Extend.
-------------

The :ref:`api` docs are full of available overrides, hook points, and
:ref:`signals`. You can provide custom classes for things like the request and
response objects. Dig deeper on the APIs you use, and look for the
customizations which are available out of the box in a Flask release. Look for
ways in which your project can be refactored into a collection of utilities and
Flask extensions. Explore the many extensions in the community, and look for
patterns to build your own extensions if you do not find the tools you need.

Subclass.
---------

The :class:`~flask.Flask` class has many methods designed for subclassing. You
can quickly add or customize behavior by subclassing :class:`~flask.Flask` (see
the linked method docs) and using that subclass wherever you instantiate an
application class. This works well with :ref:`app-factories`.

Wrap with middleware.
---------------------

The majority of code of Flask is within Werkzeug and Jinja2. These
libraries do the majority of the work. Flask is just the paste that glues
those together. For every project there is the point where the underlying
framework gets in the way (due to assumptions the original developers
had). This is natural because if this would not be the case, the
framework would be a very complex system to begin with which causes a
The :ref:`app-dispatch` chapter shows in detail how to apply middleware. You
can introduce WSGI middleware to wrap your Flask instances and introduce fixes
and changes at the layer between your Flask application and your HTTP
server. Werkzeug includes several `middlewares
<http://werkzeug.pocoo.org/docs/middlewares/>`_.

Fork.
-----

If none of the above options work, fork Flask. The majority of code of Flask
is within Werkzeug and Jinja2. These libraries do the majority of the work.
Flask is just the paste that glues those together. For every project there is
the point where the underlying framework gets in the way (due to assumptions
the original developers had). This is natural because if this would not be the
case, the framework would be a very complex system to begin with which causes a
steep learning curve and a lot of user frustration.

This is not unique to Flask. Many people use patched and modified
Expand All @@ -55,8 +67,8 @@ Furthermore integrating upstream changes can be a complex process,
depending on the number of changes. Because of that, forking should be
the very last resort.

Scaling like a Pro
------------------
Scale like a pro.
-----------------

For many web applications the complexity of the code is less an issue than
the scaling for the number of users or data entries expected. Flask by
Expand All @@ -78,11 +90,11 @@ majority of servers are using either threads, greenlets or separate
processes to achieve concurrency which are all methods well supported by
the underlying Werkzeug library.

Dialogue with the Community
Discuss with the community.
---------------------------

The Flask developers are very interested to keep everybody happy, so as
soon as you find an obstacle in your way, caused by Flask, don't hesitate
to contact the developers on the mailinglist or IRC channel. The best way
for the Flask and Flask-extension developers to improve it for larger
The Flask developers keep the framework accessible to users with codebases big
and small. If you find an obstacle in your way, caused by Flask, don't hesitate
to contact the developers on the mailinglist or IRC channel. The best way for
the Flask and Flask extension developers to improve the tools for larger
applications is getting feedback from users.
11 changes: 7 additions & 4 deletions docs/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,15 @@ The following configuration values are used internally by Flask:
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
:meth:`~flask.Flask.send_static_file` (the
default static file handler) and
:func:`~flask.send_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).
:meth:`~flask.Flask.get_send_file_max_age`
hook on :class:`~flask.Flask` or
:class:`~flask.Blueprint`,
respectively. 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
Expand Down
1 change: 1 addition & 0 deletions docs/contents.rst.inc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ instructions for web development with Flask.
:maxdepth: 2
foreword
advanced_foreword
installation
quickstart
tutorial/index
Expand Down
76 changes: 39 additions & 37 deletions docs/foreword.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,48 +8,50 @@ should or should not be using it.
What does "micro" mean?
-----------------------

“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.
“Micro” does not mean that your whole web application has to fit into a single
Python file, although it certainly can. Nor does it mean that Flask is lacking
in functionality. The "micro" in microframework means Flask aims to keep the
core simple but extensible. Flask won't make many decisions for you, such as
what database to use. Those decisions that it does make, such as what
templating engine to use, are easy to change. Everything else is up to you, so
that Flask can be everything you need and nothing you don't.

By default, Flask does not include a database abstraction layer, form
validation or anything else where different libraries already exist that can
handle that. Instead, FLask extensions add such functionality to your
application as if it was implemented in Flask itself. Numerous extensions
handle that. Instead, Flask supports extensions to add such functionality to
your application as if it was implemented in Flask itself. Numerous extensions
provide database integration, form validation, upload handling, various open
authentication technologies, and more. Flask may be "micro", but the
possibilities are endless.
authentication technologies, and more. Flask may be "micro", but it's ready for
production use on a variety of needs.

Convention over Configuration
Configuration and Conventions
-----------------------------

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.

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.

If you are curious about the Flask design principles, head over to the section
about :ref:`design`.

For the Stalwart and Wizened...
-------------------------------

If you're more curious about the minutiae of Flask's implementation, and
whether its structure is right for your needs, read the
Flask has many configuration values, with sensible defaults, and a few
conventions when getting started. By convention templates and static files are
stored in subdirectories within the application's Python source tree, with the
names `templates` and `static` respectively. While this can be changed you
usually don't have to, especially when getting started.

Growing with Flask
------------------

Once you have Flask up and running, you'll find a variety of extensions
available in the community to integrate your project for production. The Flask
core team reviews extensions and ensures approved extensions do not break with
future releases.

As your codebase grows, you are free to make the design decisions appropriate
for your project. Flask will continue to provide a very simple glue layer to
the best that Python has to offer. You can implement advanced patterns in
SQLAlchemy or another database tool, introduce non-relational data persistence
as appropriate, and take advantage of framework-agnostic tools built for WSGI,
the Python web interface.

Flask includes many hooks to customize its behavior. Should you need more
customization, the Flask class is built for subclassing. 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`.

Continue to :ref:`installation`, the :ref:`quickstart`, or the
:ref:`advanced_foreword`.
Loading

0 comments on commit 918e0aa

Please sign in to comment.