I'm building an API using Flask-restx, I'm using a token system for authentication, I'm using Flask-JWT-Extended, in my case I managed to get the token, but I'm having trouble putting it in views, I'm using a decorator
@jwt_required
decorator on views like this
class InputReaderView(Resource):
@jwt_required
def post(self):
username = get_jwt_identity()
input_reader = reqparse.RequestParser()
input_reader.add_argument("type", type=str, required=True)
input_reader.add_argument("data", type=dict, action="append", required=True)
args = input_reader.parse_args()
# datas = populate(os.path.join(BaseConfig.UPLOAD_FOLDER, 'f1040s1-tagged.json'), args['data'])
pdf_path = os.path.join(BaseConfig.UPLOAD_FOLDER, "pdf")
for pdf in os.listdir(pdf_path):
filename = secure_filename(pdf)
if filename == args["type"]:
pdf_path = os.path.join(pdf_path, filename)
datas = populate(
os.path.join(BaseConfig.UPLOAD_FOLDER, "f1040s1-tagged.json"),
args["data"],
)
validated: dict = {}
fields = extract_field(pdf_path=pdf_path)
for fv in fields:
for data in datas:
if fv["FieldName"] == data["form"]:
validated[fv["FieldName"]] = data["value"]
filled_pdf = pypdftk.fill_form(
pdf_path,
datas=validated,
out_file="{}/{}-filled.pdf".format(
os.path.join(BaseConfig.UPLOAD_FOLDER, "filled"),
filename.replace(".pdf", ""),
),
)
return jsonify(
{
"title": f"{filename}",
"filled pdf download_url": "{}{}".format(
"http://localhost:5000",
url_for(
"api.download_filled_pdf",
download_url="{}-filled.pdf".format(
filename.replace(".pdf", "")
),
)
.title()
.lower(),
),
}
)
and this is my configuration using flask-JWT-Extended on my app
# core/__init__.py
def create_app():
# import models
from apps.dashboard.models import Users
# app = Flask(f'{DemoActor.__name__}Service')
app = Flask(__name__)
app.config.from_object('core.config.ProductionConfig')
login_manager.init_app(app)
login_manager.login_view = 'api.login_view'
db.init_app(app)
migrate.init_app(app=app, db=db)
jwt.init_app(app)
# register new blueprint
app.register_blueprint(api_blueprint)
# flask context
@app.shell_context_processor
def ctx():
return {'app':app, 'db':db}
return app
# core/initial.py
"""
initialize project
"""
from flask_jwt_extended import JWTManager
from flask_login import LoginManager
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
login_manager = LoginManager()
migrate = Migrate()
db = SQLAlchemy()
jwt = JWTManager()
but I got this error
127.0.0.1 - - [14/Jul/2022 17:18:17] "POST /input-reader HTTP/1.1" 500 -
Traceback (most recent call last):
File "C:\Users\feril\Documents\Code\JOB\pallo_project\flask-dapr\venv\lib\site-packages\flask\app.py", line 2095, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\feril\Documents\Code\JOB\pallo_project\flask-dapr\venv\lib\site-packages\flask\app.py", line 2080, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\feril\Documents\Code\JOB\pallo_project\flask-dapr\venv\lib\site-packages\flask_restx\api.py", line 671, in error_router
return original_handler(f)
File "C:\Users\feril\Documents\Code\JOB\pallo_project\flask-dapr\venv\lib\site-packages\flask_restx\api.py", line 669, in error_router
return self.handle_error(e)
File "C:\Users\feril\Documents\Code\JOB\pallo_project\flask-dapr\venv\lib\site-packages\flask\app.py", line 2077, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\feril\Documents\Code\JOB\pallo_project\flask-dapr\venv\lib\site-packages\flask\app.py", line 1525, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\feril\Documents\Code\JOB\pallo_project\flask-dapr\venv\lib\site-packages\flask_restx\api.py", line 671, in error_router
return original_handler(f)
File "C:\Users\feril\Documents\Code\JOB\pallo_project\flask-dapr\venv\lib\site-packages\flask_restx\api.py", line 669, in error_router
return self.handle_error(e)
File "C:\Users\feril\Documents\Code\JOB\pallo_project\flask-dapr\venv\lib\site-packages\flask\app.py", line 1523, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\feril\Documents\Code\JOB\pallo_project\flask-dapr\venv\lib\site-packages\flask\app.py", line 1509, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "C:\Users\feril\Documents\Code\JOB\pallo_project\flask-dapr\venv\lib\site-packages\flask_restx\api.py", line 407, in wrapper
return self.make_response(data, code, headers=headers)
File "C:\Users\feril\Documents\Code\JOB\pallo_project\flask-dapr\venv\lib\site-packages\flask_restx\api.py", line 430, in make_response
resp = self.representations[mediatype](data, *args, **kwargs)
File "C:\Users\feril\Documents\Code\JOB\pallo_project\flask-dapr\venv\lib\site-packages\flask_restx\representations.py", line 25, in output_json
dumped = dumps(data, **settings) + "\n"
File "C:\src\python\lib\json\__init__.py", line 234, in dumps
return cls(
File "C:\src\python\lib\json\encoder.py", line 201, in encode
chunks = list(chunks)
File "C:\src\python\lib\json\encoder.py", line 438, in _iterencode
o = _default(o)
File "C:\src\python\lib\json\encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type function is not JSON serializable
anyone know why this? or there is an example of using Flask-JWT-Extended
with Flask-Restx
?, can it be solved?
jwt_required
should be called as followed (you're missing the brackets ()
):
class InputReaderView(Resource):
@jwt_required()
def post(self):
You can also use @jwt_required(optional=True)
which will work regardless if a token is provided or not.
References