Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask add parameter to view methods in before_request

Tags:

python

flask

Lets say I have an API at /api/something. The API requires a definition for api_key, it looks in the request arguments and the cookies. If it finds the api_key, I want it to pass the api_key to the route methods, in this case something.

@app.before_request
def pass_api_key():
    api_key = request.args.get('api_key', None)
    if api_key is None:
        api_key = request.cookies.get('api_key', None)
    if api_key is None:
        return 'api_key is required'
    # add parameter of api_key to something method

@app.route('/api/something')
def something(api_key):
    return api_key

Is this possible?

Thanks in advance.

like image 896
Patrick Lorio Avatar asked Aug 18 '13 06:08

Patrick Lorio


2 Answers

One way to do this would be to use flask.g. From the docs:

To share data that is valid for one request only from one function to another, a global variable is not good enough because it would break in threaded environments. Flask provides you with a special object that ensures it is only valid for the active request and that will return different values for each request.

Set g.api_key to the value you want to store in before_request and read it out in the route method.

flask.g, like flask.request, is what Flask and Werkzeug call a "context local" object - roughly, an object that pretends to be global, but really exposes different values to each request.

like image 154
John Sheehan Avatar answered Nov 04 '22 08:11

John Sheehan


This can be done using the url_value_processor decorator:

@app.url_value_preprocessor
def get_project_object(endpoint, values):
    api_key = values.get('api_key')
    if api_key is None:
        api_key = request.cookies.get('api_key', None)
    if api_key is None:
        raise Exception('api_key is required')
    values['api_key'] = api_key

This can also be done in a Blueprint basis, so that it only applies to the views in the specified Blueprint.

like image 38
Augusto T. Avatar answered Nov 04 '22 07:11

Augusto T.