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:
Traceback (most recent call last):
File "C:/Users/Gerasimos/Documents/Python/api_mongo/main.py", line 1, in <module>
from app import create_app
File "C:UsersGerasimosDocumentsPythonapi_mongoapp.py", line 2, in <module>
from users.api import users
File "C:UsersGerasimosDocumentsPythonapi_mongousersapi.py", line 60, in <module>
@token_required
File "C:UsersGerasimosDocumentsPythonapi_mongousersapi.py", line 31, in token_required
return decorated()
File "C:UsersGerasimosDocumentsPythonapi_mongousersapi.py", line 29, in decorated
return jsonify({'message' : 'Token is invalid!'}), 401
File "C:UsersGerasimosAppDataLocalProgramsPythonPython37-32libsite-packagesflaskjson__init__.py", line 309, in jsonify
if current_app.config['JSONIFY_PRETTYPRINT_REGULAR'] or current_app.debug:
File "C:UsersGerasimosAppDataLocalProgramsPythonPython37-32libsite-packageswerkzeuglocal.py", line 347, in __getattr__
return getattr(self._get_current_object(), name)
File "C:UsersGerasimosAppDataLocalProgramsPythonPython37-32libsite-packageswerkzeuglocal.py", line 306, in _get_current_object
return self.__local()
File "C:UsersGerasimosAppDataLocalProgramsPythonPython37-32libsite-packagesflaskglobals.py", line 51, in _find_app
raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.
This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context(). See the
documentation for more information.
My application structure:
main.py
from app import create_app
app = create_app()
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
app.py
from flask import Flask
from users.api import users
from auth.api import auth
def create_app(settings_overrides=None):
app = Flask(__name__)
configure_settings(app, settings_overrides)
configure_blueprints(app)
return app
def configure_settings(app, settings_override):
app.config.update({
'DEBUG': True,
'TESTING': True,
'JSON_SORT_KEYS': False
})
if settings_override:
app.config.update(settings_override)
def configure_blueprints(app):
app.register_blueprint(users, url_prefix='/api')
app.register_blueprint(auth, url_prefix='/api')
usersapi.py
from flask import Blueprint, request, Response, jsonify
from pymongo import MongoClient
import json
from validation.RegistrationValidator import UserSchema
from validation.UpdateUserValidator import UpdateUserSchema
from marshmallow import ValidationError
from functools import wraps
import jwt
client = MongoClient('localhost', 27017)
database = client['python_crud_api']
users_collection = database['users']
users = Blueprint('users', __name__)
SECRET_KEY = "hrtegwfjnvwivmwrhriwcg"
def token_required(f):
@wraps(f)
def decorated(*args, **kwargs):
try:
token = request.headers.get('Authorization')
data = jwt.decode(token, SECRET_KEY)
return f(*args, **kwargs)
except:
headers = {'Content-Type': 'application/json'}
return jsonify({'message' : 'Token is invalid!'}), 401
# Response(json.dumps({"message": "Unauthorized user"}), 401, headers=headers)
return decorated()
@users.route('/user', methods=['GET'])
@token_required
def get_users():
headers = {'Content-Type': 'application/json'}
all_users = users_collection.find()
result = []
# When a user is returned the password must not be in the response body
for user in all_users:
result.append({'username': user['username'], 'email': user['email']})
return Response(json.dumps({"Users": result}), status=200, headers=headers)
Advertisement
Answer
return decorated not return decorated() in token_required. Otherwise, you’ll be calling the wrapped function whenever you define a decorated function.