87 lines
2.7 KiB
ReStructuredText
87 lines
2.7 KiB
ReStructuredText
.. _hooks:
|
|
|
|
Hooks
|
|
=====
|
|
Pecan Hooks are a nice way to interact with the framework itself without having to
|
|
write WSGI middleware.
|
|
|
|
There is nothing wrong with WSGI Middleware, and actually, it is really easy to
|
|
use middleware with Pecan, but it can be hard (sometimes impossible) to have
|
|
access to Pecan's internals from within middleware. Hooks make this easier.
|
|
|
|
Hooks allow you to execute code at key points throughout the life cycle of your request:
|
|
|
|
* ``on_route``: called before Pecan attempts to route a request to a controller
|
|
|
|
* ``before``: called after routing, but before controller code is run
|
|
|
|
* ``after``: called after controller code has been run
|
|
|
|
* ``on_error``: called when a request generates an exception
|
|
|
|
Implementation
|
|
--------------
|
|
In the below example, we will write a simple hook that will gather
|
|
some information about the request and print it to ``stdout``.
|
|
|
|
Your hook implementation needs to import ``PecanHook`` so it can be used as a base class.
|
|
From there, you'll need to override the ``on_route``, ``before``, ``after``, or ``on_error`` methods::
|
|
|
|
from pecan.hooks import PecanHook
|
|
|
|
class SimpleHook(PecanHook):
|
|
|
|
def before(self, state):
|
|
print "\nabout to enter the controller..."
|
|
|
|
def after(self, state):
|
|
print "\nmethod: \t %s" % state.request.method
|
|
print "\nresponse: \t %s" % state.response.status
|
|
|
|
``on_route``, ``before``, and ``after`` are each passed a shared state object which includes useful
|
|
information about the request, such as the request and response object, and which controller
|
|
was chosen by Pecan's routing.
|
|
|
|
``on_error`` is passed a shared state object **and** the original exception.
|
|
|
|
Attaching Hooks
|
|
--------------
|
|
Hooks can be attached in a project-wide manner by specifying a list of hooks
|
|
in your project's ``app.py`` file::
|
|
|
|
from application.root import RootController
|
|
from my_hooks import SimpleHook
|
|
|
|
app = make_app(
|
|
RootController(),
|
|
hooks = [SimpleHook()]
|
|
)
|
|
|
|
Hooks can also be applied selectively to controllers and their sub-controllers
|
|
using the ``__hooks__`` attribute on one or more controllers::
|
|
|
|
from pecan import expose
|
|
from my_hooks import SimpleHook
|
|
|
|
class SimpleController(object):
|
|
|
|
__hooks__ = [SimpleHook()]
|
|
|
|
@expose('json')
|
|
def index(self):
|
|
print "DO SOMETHING!"
|
|
return dict()
|
|
|
|
Now that our ``SimpleHook`` is included, let's see what happens when we run
|
|
the app and browse the application from our web browser::
|
|
|
|
pecan serve config.py
|
|
serving on 0.0.0.0:8080 view at http://127.0.0.1:8080
|
|
|
|
about to enter the controller...
|
|
DO SOMETHING!
|
|
method: GET
|
|
response: 200 OK
|
|
|
|
|