In Falcon, hooks are type of callbacks that are defined by the user and are executed before or after a responder method in a particular resource class to process client request. They are useful in as much as they allow a client to add or overwrite request processing functionality at certain predefined stages.
Understanding Hooks in Python Falcon
Falcon offers two types of hooks:
1. Before Hooks
Executed before the corresponding responder method is invoked. They are ideal for tasks such as:
- Authentication and authorization
- Input validation and pre-processing
- Security checks
2. After Hooks
They should be called after the responder method is done with the request processing. They are typically used for:
- Logging
- Post-processing data
- Sending notifications
Using Hooks
Falcon provides two decorators, @falcon.before and @falcon.after, for hanging callbacks on responder methods, or indeed on whole classes of resources. The arguments passed to hook functions include:
req (falcon. Request): The current HTTP request object with each of the typically included objects in the request being defined as a property of the HTTP request object.
resp (falcon. Response): This is the current HTTP response instance used for the current request.
resource (object): The resource class instance of the particular request that the customer or the client wants to access.
params (dict): This is the portion of the URI template either consisting of field names and corresponding values when they are present.
Example: Authentication Hook
Let's create a simple example where we use a before hook to check for an authentication token in the request headers.
Step 1: Setting Up Falcon
Firstly, install Falcon if you haven't installed already:
pip install falconStep 2: Writing the Hook
Create a file named app.py and start by importing the necessary modules and writing the hook function:
#app.py
import falcon
# Define the authentication hook
def auth_hook(req, resp, resource, params):
token = req.get_header('Authorization')
if token != 'secret-token':
raise falcon.HTTPUnauthorized('Authentication required',
'Please provide a valid token.')
- auth_hook is a function that checks for an Authorization header in the request.
- If the token is not secret-token, it raises an HTTPUnauthorized exception, which results in a 401 Unauthorized response.
Step 3: Creating a Resource
Next, define a resource where the hook will be applied:
#app.py
# Define the resource with request handlers
class ResourceWithAuth:
@falcon.before(auth_hook)
def on_get(self, req, resp):
resp.media = {'message': 'You are authenticated!'}
@falcon.before(auth_hook)
def on_post(self, req, resp):
resp.media = {'message': 'Data received!'}
ResourceWithAuth is a resource class with two methods:
- on_get: Handles GET requests and responds with a JSON message.
- on_post: Handles POST requests and responds with a JSON message.
Step 4: Setting Up the API
Set up the Falcon API and add the route:
#app.py continue...
# Set up the Falcon API and add the route
app = falcon.App()
app.add_route('/secure', ResourceWithAuth())
# Run the application using the built-in WSGI server
if __name__ == '__main__':
from wsgiref.simple_server import make_server
with make_server('', 8000, app) as httpd:
print('Serving on port 8000...')
httpd.serve_forever()
Running the Application
Run your Falcon application, using:
python app.pyYou should see the output indicating that the server is running:

Testing the Hook
Let's test our before hook using curl:
Without Token
curl -i http://localhost:8000/secureOutput:

With Token
curl -i -H "Authorization: secret-token" http://localhost:8000/secureOutput:

Example: Logging (After Hooks)
After hooks are defined similarly but are used to modify the response:
Setting Up Logging:
import falcon
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
- This sets up basic logging configuration with the log level set to INFO.
- logger is an instance of a logger to log messages.
Defining the After Hook:
def add_custom_header(req, resp, resource, req_succeeded):
logger.info(f"Processing {req.method} request for {req.path}")
resp.set_header('X-Custom-Header', 'CustomValue')
- add_custom_header is a function that constructs a log message using the request method, the requested URI, and the response status.
- The log message is then logged using logger.info.
Creating the Resource with Request Handlers:
class ResourceWithAfterHook:
@falcon.after(add_custom_header)
def on_get(self, req, resp):
logger.info("Handling GET request")
resp.media = {'message': 'Response with a custom header!'}
@falcon.after(add_custom_header)
def on_post(self, req, resp):
logger.info("Handling POST request")
resp.media = {'message': 'Data received with a custom header!'}
ResourceWithAfterHook is a resource class with two methods:
- on_get: Handles GET requests and responds with a JSON message.
- on_post: Handles POST requests and responds with a JSON message.
The @falcon.after(add_custom_header) decorator applies the add_custom_header hook to both methods.
Setting Up the Falcon API and Adding the Route:
app = falcon.App()
app.add_route('/custom', ResourceWithAfterHook())
Running the Application:
if __name__ == '__main__':
from wsgiref.simple_server import make_server
with make_server('', 8000, app) as httpd:
print('Serving on port 8000...')
httpd.serve_forever()
This block of code checks if the script is being run directly.
It uses Python's built-in WSGI server to serve the Falcon application on port 8000.
Testing the After Hook
To test the application and see the logging in action, you can use curl or any other HTTP client:
GET Request
curl -i http://localhost:8000/customPOST Request
curl -i -X POST http://localhost:8000/customAdvanced Hook Usage
Multiple Hooks
You can apply multiple hooks to a resource. Just chain them together using the Falcon decorators:
@falcon.before(auth_hook)
@falcon.before(another_hook)
class AnotherResource:
def on_get(self, req, resp):
resp.media = {'message': 'Multiple hooks applied!'}
By using Falcon hooks, we achieve clean separation of concerns, making our code more modular and easier to maintain.
Common Use Cases for Falcon Hooks
Authentication and Authorization:
Before hooks can be used to enforce some certain levels of authentication and authorization mechanisms by checking user credentials or tokens before granting the users access to the protected resources.
Logging:
When using hooks, after hooks in particular are usually followed by logging of the request and response details, including request method, URL, status, as well as execution time for diagnostics and control purposes.
Request Validation:
Before hooks can get a hold of incoming requests to check whether they meet specific criteria, it is essential to understand that all requests shall meet certain requirements like required parameters, data types, or format.
Response Manipulation:
Next paradigms allow hooks so that the actual content of the response, or the headers in which it is returned to the client, can be changed according to certain needs.
Caching:
Both before and after hooks can be used for caching strategies For the before hooks can check if it is there a cached response then it will immediately serve it , whereas after hooks can cache the response generated now to serve it in future similar requests.
Metrics Collection:
After hooks are discussed as a tool to capture metrics which are typically associated with API utilization for monitoring and optimization purposes such as the number of requests to the API, time taken to process requests, number of errors, etc.