Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/app/static/doc/flask-docs/_sources/reqcontext.txt
diff options
context:
space:
mode:
Diffstat (limited to 'app/static/doc/flask-docs/_sources/reqcontext.txt')
-rw-r--r--app/static/doc/flask-docs/_sources/reqcontext.txt239
1 files changed, 239 insertions, 0 deletions
diff --git a/app/static/doc/flask-docs/_sources/reqcontext.txt b/app/static/doc/flask-docs/_sources/reqcontext.txt
new file mode 100644
index 0000000..0249b88
--- /dev/null
+++ b/app/static/doc/flask-docs/_sources/reqcontext.txt
@@ -0,0 +1,239 @@
+.. _request-context:
+
+The Request Context
+===================
+
+This document describes the behavior in Flask 0.7 which is mostly in line
+with the old behavior but has some small, subtle differences.
+
+One of the design ideas behind Flask is that there are two different
+“states” in which code is executed. The application setup state in which
+the application implicitly is on the module level. It starts when the
+:class:`Flask` object is instantiated, and it implicitly ends when the
+first request comes in. While the application is in this state a few
+assumptions are true:
+
+- the programmer can modify the application object safely.
+- no request handling happened so far
+- you have to have a reference to the application object in order to
+ modify it, there is no magic proxy that can give you a reference to
+ the application object you're currently creating or modifying.
+
+On the contrast, during request handling, a couple of other rules exist:
+
+- while a request is active, the context local objects
+ (:data:`flask.request` and others) point to the current request.
+- any code can get hold of these objects at any time.
+
+The magic that makes this works is internally referred in Flask as the
+“request context”.
+
+Diving into Context Locals
+--------------------------
+
+Say you have a utility function that returns the URL the user should be
+redirected to. Imagine it would always redirect to the URL's ``next``
+parameter or the HTTP referrer or the index page::
+
+ from flask import request, url_for
+
+ def redirect_url():
+ return request.args.get('next') or \
+ request.referrer or \
+ url_for('index')
+
+As you can see, it accesses the request object. If you try to run this
+from a plain Python shell, this is the exception you will see:
+
+>>> redirect_url()
+Traceback (most recent call last):
+ File "<stdin>", line 1, in <module>
+AttributeError: 'NoneType' object has no attribute 'request'
+
+That makes a lot of sense because we currently do not have a request we
+could access. So we have to make a request and bind it to the current
+context. The :attr:`~flask.Flask.test_request_context` method can create
+us a :class:`~flask.ctx.RequestContext`:
+
+>>> ctx = app.test_request_context('/?next=http://example.com/')
+
+This context can be used in two ways. Either with the `with` statement
+or by calling the :meth:`~flask.ctx.RequestContext.push` and
+:meth:`~flask.ctx.RequestContext.pop` methods:
+
+>>> ctx.push()
+
+From that point onwards you can work with the request object:
+
+>>> redirect_url()
+u'http://example.com/'
+
+Until you call `pop`:
+
+>>> ctx.pop()
+
+Because the request context is internally maintained as a stack you can
+push and pop multiple times. This is very handy to implement things like
+internal redirects.
+
+For more information of how to utilize the request context from the
+interactive Python shell, head over to the :ref:`shell` chapter.
+
+How the Context Works
+---------------------
+
+If you look into how the Flask WSGI application internally works, you will
+find a piece of code that looks very much like this::
+
+ def wsgi_app(self, environ):
+ with self.request_context(environ):
+ try:
+ response = self.full_dispatch_request()
+ except Exception, e:
+ response = self.make_response(self.handle_exception(e))
+ return response(environ, start_response)
+
+The method :meth:`~Flask.request_context` returns a new
+:class:`~flask.ctx.RequestContext` object and uses it in combination with
+the `with` statement to bind the context. Everything that is called from
+the same thread from this point onwards until the end of the `with`
+statement will have access to the request globals (:data:`flask.request`
+and others).
+
+The request context internally works like a stack: The topmost level on
+the stack is the current active request.
+:meth:`~flask.ctx.RequestContext.push` adds the context to the stack on
+the very top, :meth:`~flask.ctx.RequestContext.pop` removes it from the
+stack again. On popping the application's
+:func:`~flask.Flask.teardown_request` functions are also executed.
+
+.. _callbacks-and-errors:
+
+Callbacks and Errors
+--------------------
+
+What happens if an error occurs in Flask during request processing? This
+particular behavior changed in 0.7 because we wanted to make it easier to
+understand what is actually happening. The new behavior is quite simple:
+
+1. Before each request, :meth:`~flask.Flask.before_request` functions are
+ executed. If one of these functions return a response, the other
+ functions are no longer called. In any case however the return value
+ is treated as a replacement for the view's return value.
+
+2. If the :meth:`~flask.Flask.before_request` functions did not return a
+ response, the regular request handling kicks in and the view function
+ that was matched has the chance to return a response.
+
+3. The return value of the view is then converted into an actual response
+ object and handed over to the :meth:`~flask.Flask.after_request`
+ functions which have the chance to replace it or modify it in place.
+
+4. At the end of the request the :meth:`~flask.Flask.teardown_request`
+ functions are executed. This always happens, even in case of an
+ unhandled exception down the road or if a before-request handler was
+ not executed yet or at all (for example in test environments sometimes
+ you might want to not execute before-request callbacks).
+
+Now what happens on errors? In production mode if an exception is not
+caught, the 500 internal server handler is called. In development mode
+however the exception is not further processed and bubbles up to the WSGI
+server. That way things like the interactive debugger can provide helpful
+debug information.
+
+An important change in 0.7 is that the internal server error is now no
+longer post processed by the after request callbacks and after request
+callbacks are no longer guaranteed to be executed. This way the internal
+dispatching code looks cleaner and is easier to customize and understand.
+
+The new teardown functions are supposed to be used as a replacement for
+things that absolutely need to happen at the end of request.
+
+Teardown Callbacks
+------------------
+
+The teardown callbacks are special callbacks in that they are executed at
+at different point. Strictly speaking they are independent of the actual
+request handling as they are bound to the lifecycle of the
+:class:`~flask.ctx.RequestContext` object. When the request context is
+popped, the :meth:`~flask.Flask.teardown_request` functions are called.
+
+This is important to know if the life of the request context is prolonged
+by using the test client in a with statement or when using the request
+context from the command line::
+
+ with app.test_client() as client:
+ resp = client.get('/foo')
+ # the teardown functions are still not called at that point
+ # even though the response ended and you have the response
+ # object in your hand
+
+ # only when the code reaches this point the teardown functions
+ # are called. Alternatively the same thing happens if another
+ # request was triggered from the test client
+
+It's easy to see the behavior from the command line:
+
+>>> app = Flask(__name__)
+>>> @app.teardown_request
+... def teardown_request(exception=None):
+... print 'this runs after request'
+...
+>>> ctx = app.test_request_context()
+>>> ctx.push()
+>>> ctx.pop()
+this runs after request
+>>>
+
+Keep in mind that teardown callbacks are always executed, even if
+before-request callbacks were not executed yet but an exception happened.
+Certain parts of the test system might also temporarily create a request
+context without calling the before-request handlers. Make sure to write
+your teardown-request handlers in a way that they will never fail.
+
+.. _notes-on-proxies:
+
+Notes On Proxies
+----------------
+
+Some of the objects provided by Flask are proxies to other objects. The
+reason behind this is that these proxies are shared between threads and
+they have to dispatch to the actual object bound to a thread behind the
+scenes as necessary.
+
+Most of the time you don't have to care about that, but there are some
+exceptions where it is good to know that this object is an actual proxy:
+
+- The proxy objects do not fake their inherited types, so if you want to
+ perform actual instance checks, you have to do that on the instance
+ that is being proxied (see `_get_current_object` below).
+- if the object reference is important (so for example for sending
+ :ref:`signals`)
+
+If you need to get access to the underlying object that is proxied, you
+can use the :meth:`~werkzeug.local.LocalProxy._get_current_object` method::
+
+ app = current_app._get_current_object()
+ my_signal.send(app)
+
+Context Preservation on Error
+-----------------------------
+
+If an error occurs or not, at the end of the request the request context
+is popped and all data associated with it is destroyed. During
+development however that can be problematic as you might want to have the
+information around for a longer time in case an exception occurred. In
+Flask 0.6 and earlier in debug mode, if an exception occurred, the
+request context was not popped so that the interactive debugger can still
+provide you with important information.
+
+Starting with Flask 0.7 you have finer control over that behavior by
+setting the ``PRESERVE_CONTEXT_ON_EXCEPTION`` configuration variable. By
+default it's linked to the setting of ``DEBUG``. If the application is in
+debug mode the context is preserved, in production mode it's not.
+
+Do not force activate ``PRESERVE_CONTEXT_ON_EXCEPTION`` in production mode
+as it will cause your application to leak memory on exceptions. However
+it can be useful during development to get the same error preserving
+behavior as in development mode when attempting to debug an error that
+only occurs under production settings.