使用装饰器时如何使用 flask app context
How to use flask app context when using decorators
我想为此“文章”端点使用来自 Flask-Security-Too 的令牌授权。但是,装饰器函数 @auth_token_required("token")
需要应用程序的上下文。该应用程序在不同的文件中初始化。
我已经添加了 app.app_context()
但我不知道如何告诉装饰器使用它的上下文。
注意:我正在与 Flask-RestX 合作提供 SwaggerUI(和 OpenAPI 规范)。另外,我使用 Blueprints/Namespaces 来模块化 API - 这使得它有点复杂。
from flask import Blueprint
from flask_restx import Api, Resource, fields, Namespace
from flask_security import auth_token_required
from .db import db_session
from .models import Article
from flask import current_app as app
article_blueprint = Blueprint('api', __name__, url_prefix='/api/article')
flask_api = Api(article_blueprint, version='0.1', title='Article Manager',
description='Article management',)
article_manager = Namespace('article', description='Article Management Endpoint')
parser = article_manager.parser()
parser.add_argument('title', type=str, required=False,
help='Title of Article', location='json')
parser.add_argument('text', type=str, required=False,
help='Text of Article', location='json')
parser.add_argument('id', type=int, required=False,
help='ID of Article', location='json')
@article_manager.route('/<string:title>','/<int:id>')
class GetArticle(Resource):
# FIXME app.app_context() ?!
@auth_token_required("token")
def get(self, title=None, id=None):
# removed error handling for simplicity
if title is not None:
data = Article.query.filter(Article.title.ilike('%'+title+'%')).first()
if id is not None:
data = Article.query.filter_by(id=id).first()
db_session.commit()
return {'id': data.id, 'title': data.title, 'text': data.text}, 200
flask_api.add_namespace(article_manager)
Flask 告诉我:
Exception has occurred: RuntimeError
Working outside of application context.
我不熟悉 flask_restx - 但是 - app_context 是在 flask 首次处理请求时自动创建的。您没有提及何时收到此错误 - 在配置时间或实际请求时间(或者是在您调用 add_namespace 时?)。您可能想查看:https://flask.palletsprojects.com/en/2.0.x/appcontext/ 以了解有关 appcontext 的更多信息。
问题出在auth_token_required装饰器的使用方式上。 auth_token_required
decorator unlike auth_required
不接受任何额外的配置参数,并期望传输唯一的修饰函数。
您的代码可以通过应用以下变体之一来修复:
@article_manager.route('/<string:title>', '/<int:id>')
class GetArticle(Resource):
@auth_token_required
def get(self, title=None, id=None):
pass
或
@article_manager.route('/<string:title>', '/<int:id>')
class GetArticle(Resource):
@auth_required("token")
def get(self, title=None, id=None):
pass
我想为此“文章”端点使用来自 Flask-Security-Too 的令牌授权。但是,装饰器函数 @auth_token_required("token")
需要应用程序的上下文。该应用程序在不同的文件中初始化。
我已经添加了 app.app_context()
但我不知道如何告诉装饰器使用它的上下文。
注意:我正在与 Flask-RestX 合作提供 SwaggerUI(和 OpenAPI 规范)。另外,我使用 Blueprints/Namespaces 来模块化 API - 这使得它有点复杂。
from flask import Blueprint
from flask_restx import Api, Resource, fields, Namespace
from flask_security import auth_token_required
from .db import db_session
from .models import Article
from flask import current_app as app
article_blueprint = Blueprint('api', __name__, url_prefix='/api/article')
flask_api = Api(article_blueprint, version='0.1', title='Article Manager',
description='Article management',)
article_manager = Namespace('article', description='Article Management Endpoint')
parser = article_manager.parser()
parser.add_argument('title', type=str, required=False,
help='Title of Article', location='json')
parser.add_argument('text', type=str, required=False,
help='Text of Article', location='json')
parser.add_argument('id', type=int, required=False,
help='ID of Article', location='json')
@article_manager.route('/<string:title>','/<int:id>')
class GetArticle(Resource):
# FIXME app.app_context() ?!
@auth_token_required("token")
def get(self, title=None, id=None):
# removed error handling for simplicity
if title is not None:
data = Article.query.filter(Article.title.ilike('%'+title+'%')).first()
if id is not None:
data = Article.query.filter_by(id=id).first()
db_session.commit()
return {'id': data.id, 'title': data.title, 'text': data.text}, 200
flask_api.add_namespace(article_manager)
Flask 告诉我:
Exception has occurred: RuntimeError
Working outside of application context.
我不熟悉 flask_restx - 但是 - app_context 是在 flask 首次处理请求时自动创建的。您没有提及何时收到此错误 - 在配置时间或实际请求时间(或者是在您调用 add_namespace 时?)。您可能想查看:https://flask.palletsprojects.com/en/2.0.x/appcontext/ 以了解有关 appcontext 的更多信息。
问题出在auth_token_required装饰器的使用方式上。 auth_token_required
decorator unlike auth_required
不接受任何额外的配置参数,并期望传输唯一的修饰函数。
您的代码可以通过应用以下变体之一来修复:
@article_manager.route('/<string:title>', '/<int:id>')
class GetArticle(Resource):
@auth_token_required
def get(self, title=None, id=None):
pass
或
@article_manager.route('/<string:title>', '/<int:id>')
class GetArticle(Resource):
@auth_required("token")
def get(self, title=None, id=None):
pass