Last Updated: February 25, 2016
·
25.46K
· spencerwi

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.

2 Responses
Add your response

Well, this is odd. Looks like Coderwall munged the "at" in the decorators into links. weird.

over 1 year ago ·

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.

over 1 year ago ·