Require an API key for a route in Flask using only a decorator
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.
Written by Spencer Williams
Related protips
2 Responses
Well, this is odd. Looks like Coderwall munged the "at" in the decorators into links. weird.
Yeah code snippets got broken by coderwall... submit a bug to them :) Anyway the decorator way is really clean and nice solution in situation like this. Nice tip.