diff options
Diffstat (limited to 'app/static/doc/flask-docs/_sources/signals.txt')
-rw-r--r-- | app/static/doc/flask-docs/_sources/signals.txt | 255 |
1 files changed, 0 insertions, 255 deletions
diff --git a/app/static/doc/flask-docs/_sources/signals.txt b/app/static/doc/flask-docs/_sources/signals.txt deleted file mode 100644 index 0d1d9ee..0000000 --- a/app/static/doc/flask-docs/_sources/signals.txt +++ /dev/null @@ -1,255 +0,0 @@ -.. _signals: - -Signals -======= - -.. versionadded:: 0.6 - -Starting with Flask 0.6, there is integrated support for signalling in -Flask. This support is provided by the excellent `blinker`_ library and -will gracefully fall back if it is not available. - -What are signals? Signals help you decouple applications by sending -notifications when actions occur elsewhere in the core framework or -another Flask extensions. In short, signals allow certain senders to -notify subscribers that something happened. - -Flask comes with a couple of signals and other extensions might provide -more. Also keep in mind that signals are intended to notify subscribers -and should not encourage subscribers to modify data. You will notice that -there are signals that appear to do the same thing like some of the -builtin decorators do (eg: :data:`~flask.request_started` is very similar -to :meth:`~flask.Flask.before_request`). There are however difference in -how they work. The core :meth:`~flask.Flask.before_request` handler for -example is executed in a specific order and is able to abort the request -early by returning a response. In contrast all signal handlers are -executed in undefined order and do not modify any data. - -The big advantage of signals over handlers is that you can safely -subscribe to them for the split of a second. These temporary -subscriptions are helpful for unittesting for example. Say you want to -know what templates were rendered as part of a request: signals allow you -to do exactly that. - -Subscribing to Signals ----------------------- - -To subscribe to a signal, you can use the -:meth:`~blinker.base.Signal.connect` method of a signal. The first -argument is the function that should be called when the signal is emitted, -the optional second argument specifies a sender. To unsubscribe from a -signal, you can use the :meth:`~blinker.base.Signal.disconnect` method. - -For all core Flask signals, the sender is the application that issued the -signal. When you subscribe to a signal, be sure to also provide a sender -unless you really want to listen for signals of all applications. This is -especially true if you are developing an extension. - -Here for example a helper context manager that can be used to figure out -in a unittest which templates were rendered and what variables were passed -to the template:: - - from flask import template_rendered - from contextlib import contextmanager - - @contextmanager - def captured_templates(app): - recorded = [] - def record(sender, template, context): - recorded.append((template, context)) - template_rendered.connect(record, app) - try: - yield recorded - finally: - template_rendered.disconnect(record, app) - -This can now easily be paired with a test client:: - - with captured_templates(app) as templates: - rv = app.test_client().get('/') - assert rv.status_code == 200 - assert len(templates) == 1 - template, context = templates[0] - assert template.name == 'index.html' - assert len(context['items']) == 10 - -All the template rendering in the code issued by the application `app` -in the body of the `with` block will now be recorded in the `templates` -variable. Whenever a template is rendered, the template object as well as -context are appended to it. - -Additionally there is a convenient helper method -(:meth:`~blinker.base.Signal.connected_to`). that allows you to -temporarily subscribe a function to a signal with is a context manager on -its own. Because the return value of the context manager cannot be -specified that way one has to pass the list in as argument:: - - from flask import template_rendered - - def captured_templates(app, recorded): - def record(sender, template, context): - recorded.append((template, context)) - return template_rendered.connected_to(record, app) - -The example above would then look like this:: - - templates = [] - with captured_templates(app, templates): - ... - template, context = templates[0] - -.. admonition:: Blinker API Changes - - The :meth:`~blinker.base.Signal.connected_to` method arrived in Blinker - with version 1.1. - -Creating Signals ----------------- - -If you want to use signals in your own application, you can use the -blinker library directly. The most common use case are named signals in a -custom :class:`~blinker.base.Namespace`.. This is what is recommended -most of the time:: - - from blinker import Namespace - my_signals = Namespace() - -Now you can create new signals like this:: - - model_saved = my_signals.signal('model-saved') - -The name for the signal here makes it unique and also simplifies -debugging. You can access the name of the signal with the -:attr:`~blinker.base.NamedSignal.name` attribute. - -.. admonition:: For Extension Developers - - If you are writing a Flask extension and you want to gracefully degrade for - missing blinker installations, you can do so by using the - :class:`flask.signals.Namespace` class. - -Sending Signals ---------------- - -If you want to emit a signal, you can do so by calling the -:meth:`~blinker.base.Signal.send` method. It accepts a sender as first -argument and optionally some keyword arguments that are forwarded to the -signal subscribers:: - - class Model(object): - ... - - def save(self): - model_saved.send(self) - -Try to always pick a good sender. If you have a class that is emitting a -signal, pass `self` as sender. If you emitting a signal from a random -function, you can pass ``current_app._get_current_object()`` as sender. - -.. admonition:: Passing Proxies as Senders - - Never pass :data:`~flask.current_app` as sender to a signal. Use - ``current_app._get_current_object()`` instead. The reason for this is - that :data:`~flask.current_app` is a proxy and not the real application - object. - -Decorator Based Signal Subscriptions ------------------------------------- - -With Blinker 1.1 you can also easily subscribe to signals by using the new -:meth:`~blinker.base.NamedSignal.connect_via` decorator:: - - from flask import template_rendered - - @template_rendered.connect_via(app) - def when_template_rendered(sender, template, context): - print 'Template %s is rendered with %s' % (template.name, context) - -Core Signals ------------- - -.. when modifying this list, also update the one in api.rst - -The following signals exist in Flask: - -.. data:: flask.template_rendered - :noindex: - - This signal is sent when a template was successfully rendered. The - signal is invoked with the instance of the template as `template` - and the context as dictionary (named `context`). - - Example subscriber:: - - def log_template_renders(sender, template, context): - sender.logger.debug('Rendering template "%s" with context %s', - template.name or 'string template', - context) - - from flask import template_rendered - template_rendered.connect(log_template_renders, app) - -.. data:: flask.request_started - :noindex: - - This signal is sent before any request processing started but when the - request context was set up. Because the request context is already - bound, the subscriber can access the request with the standard global - proxies such as :class:`~flask.request`. - - Example subscriber:: - - def log_request(sender): - sender.logger.debug('Request context is set up') - - from flask import request_started - request_started.connect(log_request, app) - -.. data:: flask.request_finished - :noindex: - - This signal is sent right before the response is sent to the client. - It is passed the response to be sent named `response`. - - Example subscriber:: - - def log_response(sender, response): - sender.logger.debug('Request context is about to close down. ' - 'Response: %s', response) - - from flask import request_finished - request_finished.connect(log_response, app) - -.. data:: flask.got_request_exception - :noindex: - - This signal is sent when an exception happens during request processing. - It is sent *before* the standard exception handling kicks in and even - in debug mode, where no exception handling happens. The exception - itself is passed to the subscriber as `exception`. - - Example subscriber:: - - def log_exception(sender, exception): - sender.logger.debug('Got exception during processing: %s', exception) - - from flask import got_request_exception - got_request_exception.connect(log_exception, app) - -.. data:: flask.request_tearing_down - :noindex: - - This signal is sent when the request is tearing down. This is always - called, even if an exception is caused. Currently functions listening - to this signal are called after the regular teardown handlers, but this - is not something you can rely on. - - Example subscriber:: - - def close_db_connection(sender): - session.close() - - from flask import request_tearing_down - request_tearing_down.connect(close_db_connection, app) - -.. _blinker: http://pypi.python.org/pypi/blinker |