I am fairly new to Flask applications. While my application works for all the endpoints as expected when I tried to add jwt authorization I encountered this issue. I have tried this solution app.app_context().push() based on some other questions that have been posted.
Any help would be greatly appreciated. I would also like to use the decorator in multiple apis, should I include the token_required function in each one, or best practise would be to be imported?
Error:
JavaScript
x
26
26
1
Traceback (most recent call last):
2
File "C:/Users/Gerasimos/Documents/Python/api_mongo/main.py", line 1, in <module>
3
from app import create_app
4
File "C:UsersGerasimosDocumentsPythonapi_mongoapp.py", line 2, in <module>
5
from users.api import users
6
File "C:UsersGerasimosDocumentsPythonapi_mongousersapi.py", line 60, in <module>
7
@token_required
8
File "C:UsersGerasimosDocumentsPythonapi_mongousersapi.py", line 31, in token_required
9
return decorated()
10
File "C:UsersGerasimosDocumentsPythonapi_mongousersapi.py", line 29, in decorated
11
return jsonify({'message' : 'Token is invalid!'}), 401
12
File "C:UsersGerasimosAppDataLocalProgramsPythonPython37-32libsite-packagesflaskjson__init__.py", line 309, in jsonify
13
if current_app.config['JSONIFY_PRETTYPRINT_REGULAR'] or current_app.debug:
14
File "C:UsersGerasimosAppDataLocalProgramsPythonPython37-32libsite-packageswerkzeuglocal.py", line 347, in __getattr__
15
return getattr(self._get_current_object(), name)
16
File "C:UsersGerasimosAppDataLocalProgramsPythonPython37-32libsite-packageswerkzeuglocal.py", line 306, in _get_current_object
17
return self.__local()
18
File "C:UsersGerasimosAppDataLocalProgramsPythonPython37-32libsite-packagesflaskglobals.py", line 51, in _find_app
19
raise RuntimeError(_app_ctx_err_msg)
20
RuntimeError: Working outside of application context.
21
22
This typically means that you attempted to use functionality that needed
23
to interface with the current application object in some way. To solve
24
this, set up an application context with app.app_context(). See the
25
documentation for more information.
26
My application structure:
main.py
JavaScript
1
7
1
from app import create_app
2
3
app = create_app()
4
5
if __name__ == '__main__':
6
app.run(host='0.0.0.0', port=5000, debug=True)
7
app.py
JavaScript
1
26
26
1
from flask import Flask
2
from users.api import users
3
from auth.api import auth
4
5
6
def create_app(settings_overrides=None):
7
app = Flask(__name__)
8
configure_settings(app, settings_overrides)
9
configure_blueprints(app)
10
return app
11
12
13
def configure_settings(app, settings_override):
14
app.config.update({
15
'DEBUG': True,
16
'TESTING': True,
17
'JSON_SORT_KEYS': False
18
})
19
if settings_override:
20
app.config.update(settings_override)
21
22
23
def configure_blueprints(app):
24
app.register_blueprint(users, url_prefix='/api')
25
app.register_blueprint(auth, url_prefix='/api')
26
usersapi.py
JavaScript
1
45
45
1
from flask import Blueprint, request, Response, jsonify
2
from pymongo import MongoClient
3
import json
4
from validation.RegistrationValidator import UserSchema
5
from validation.UpdateUserValidator import UpdateUserSchema
6
from marshmallow import ValidationError
7
from functools import wraps
8
import jwt
9
10
client = MongoClient('localhost', 27017)
11
database = client['python_crud_api']
12
users_collection = database['users']
13
14
users = Blueprint('users', __name__)
15
16
SECRET_KEY = "hrtegwfjnvwivmwrhriwcg"
17
18
19
def token_required(f):
20
@wraps(f)
21
def decorated(*args, **kwargs):
22
try:
23
token = request.headers.get('Authorization')
24
data = jwt.decode(token, SECRET_KEY)
25
return f(*args, **kwargs)
26
except:
27
headers = {'Content-Type': 'application/json'}
28
return jsonify({'message' : 'Token is invalid!'}), 401
29
# Response(json.dumps({"message": "Unauthorized user"}), 401, headers=headers)
30
return decorated()
31
32
33
@users.route('/user', methods=['GET'])
34
@token_required
35
def get_users():
36
headers = {'Content-Type': 'application/json'}
37
38
all_users = users_collection.find()
39
result = []
40
# When a user is returned the password must not be in the response body
41
for user in all_users:
42
result.append({'username': user['username'], 'email': user['email']})
43
44
return Response(json.dumps({"Users": result}), status=200, headers=headers)
45
Advertisement
Answer
return decorated
not return decorated()
in token_required
. Otherwise, you’ll be calling the wrapped function whenever you define a decorated function.