Python decorators are great, if not always straightforward to define.
Flask is a great Python library for building REST APIs; it makes use of decorators heavily for things like this:
@route('/') def index(): return "index page! Woo!"
But when building a REST API around protected resources, you often need to require an API key for certain routes (like, for example PUT to "/users/").
Now, you could go and write code in each view to validate an API key. You might even write a function that does that and just call the function within your views.
Personally, I prefer to use decorators. It's just cleaner and simpler.
Now, to do so, you have to define a decorator, and that is a bit ugly:
from functools import wraps from flask import request, abort # The actual decorator function def require_appkey(view_function): @wraps(view_function) # the new, post-decoration function. Note *args and **kwargs here. def decorated_function(*args, **kwargs): if request.args.get('key') and request.args.get('key') == APPKEY_HERE: return view_function(*args, **kwargs) else: abort(401) return decorated_function
Now you can do things like this:
@route('/users/', methods=['PUT']) @require_appkey def put_user(): ...
As is always the case with decorator in Flask, the
route decorator must be the outermost decorator for this to work properly.