I'm trying use this answer to my problem, but I don't know how to it use correctly.
My code:
app = Flask(name)
app = Flask(__name__, static_folder="static", static_path="")
class SecuredStaticFlask(app):
def send_static_file(self, filename):
# Get user from session
if current_user.is_authenticated():
return super(SecuredStaticFlask, self).send_static_file(filename)
else:
abort(403)
When I visit http://localhost:5000/some_existing_file in the browser, Flask give me an error:
Traceback (most recent call last):
File "/home/honza/Stažené/pycharm-community-3.0/helpers/pydev/pydevd.py", line 1498, in <module>
debugger.run(setup['file'], None, None)
File "/home/honza/Stažené/pycharm-community-3.0/helpers/pydev/pydevd.py", line 1139, in run
pydev_imports.execfile(file, globals, locals) #execute the script
File "/home/honza/workspace/web_development/login/toneid_web_api_jk.py", line 37, in <module>
class SecuredStaticFlask(app):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 507, in __init__
self.add_url_rule(self.static_url_path + '/<path:filename>',
TypeError: Error when calling the metaclass bases
can only concatenate tuple (not "str") to tuple
Instance of flask.Flask is app, right? So, I think subclass of Flask is subclass_name(parent_class).
Can anybody help me? Thanks.
In my opinion it should be in lines of :
class SecuredStaticFlask(Flask):
def send_static_file(self, filename):
# Get user from session
if current_user.is_authenticated():
return super(SecuredStaticFlask, self).send_static_file(filename)
else:
abort(403)
and
app = SecuredStaticFlask(__name__, static_folder="static", static_path="")
Related
I'm programming a Website with Authentification while using the Flask Framework. I've tried every solution that i found on the internet but nothing worked for me.
My first idea was, that the Project Structure was corrupt. e.g. missing imports from other files. But thats not the problem i think.
My models.py File:
from flask_login import UserMixin, LoginManager
from flaskapp import db, login_manager
#login_manager.user_loader
def get_user(user):
try:
return get_id(user)
except:
return None
class User(db.Model,UserMixin):
id =db.Column(db.Integer, primary_key=True)
username =db.Column(db.String(20),unique=True, nullable=False)
email =db.Column(db.String(120), unique=True, nullable=False)
password =db.Column(db.String(60), nullable=False)
powerlevel =db.Column(db.Integer, nullable=False)
def is_authenticated(self):
return True
def is_active(self):
return True
def is_anonymous(self):
return False
def get_id(self):
return int(self.id)
def __repr__(self):
return f"User('{self.username}', '{self.email}', '{self.powerlevel}')"
My init.py File:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
app = Flask(__name__)
app.config['SECRET_KEY'] = 'xxx'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login'
login_manager = login_message_category = 'info'
from flaskapp import routes
When running the WebApp using:
export FLASK_APP=run.py DEBUG=TRUE
flask run
Following Error Message Occurs:
Traceback (most recent call last):
File "/home/osboxes/.local/bin/flask", line 11, in <module>
sys.exit(main())
File "/home/osboxes/.local/lib/python3.6/site-packages/flask/cli.py", line 966, in main
cli.main(prog_name="python -m flask" if as_module else None)
File "/home/osboxes/.local/lib/python3.6/site-packages/flask/cli.py", line 586, in main
return super(FlaskGroup, self).main(*args, **kwargs)
File "/home/osboxes/.local/lib/python3.6/site-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/home/osboxes/.local/lib/python3.6/site-packages/click/core.py", line 1137, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/home/osboxes/.local/lib/python3.6/site-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/osboxes/.local/lib/python3.6/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/home/osboxes/.local/lib/python3.6/site-packages/click/decorators.py", line 64, in new_func
return ctx.invoke(f, obj, *args, **kwargs)
File "/home/osboxes/.local/lib/python3.6/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/home/osboxes/.local/lib/python3.6/site-packages/flask/cli.py", line 848, in run_command
app = DispatchingApp(info.load_app, use_eager_loading=eager_loading)
File "/home/osboxes/.local/lib/python3.6/site-packages/flask/cli.py", line 305, in __init__
self._load_unlocked()
File "/home/osboxes/.local/lib/python3.6/site-packages/flask/cli.py", line 330, in _load_unlocked
self._app = rv = self.loader()
File "/home/osboxes/.local/lib/python3.6/site-packages/flask/cli.py", line 388, in load_app
app = locate_app(self, import_name, name)
File "/home/osboxes/.local/lib/python3.6/site-packages/flask/cli.py", line 240, in locate_app
__import__(module_name)
File "/home/osboxes/Desktop/HMI/run.py", line 1, in <module>
from flaskapp import app
File "/home/osboxes/Desktop/HMI/flaskapp/__init__.py", line 21, in <module>
from flaskapp import routes
File "/home/osboxes/Desktop/HMI/flaskapp/routes.py", line 6, in <module>
from flaskapp.models import User
File "/home/osboxes/Desktop/HMI/flaskapp/models.py", line 7, in <module>
#login_manager.user_loader
AttributeError: 'str' object has no attribute 'user_loader'
Right now i don't know what else could be the problem.
If i forgot to supply some code for solving the error, let me know.
Thank you for your Help!
First, your User.get_id should be returning unicode not an int. The documentation mentions this, along with an example:
This method must return a unicode that uniquely identifies this user,
and can be used to load the user from the user_loader callback. Note
that this must be a unicode - if the ID is natively an int or some
other type, you will need to convert it to unicode. (Your User
Class)
So that needs to be changed to:
def get_id(self):
return unicode(self.id)
Next up, your user_loader. From the docs:
This sets the callback for reloading a user from the session. The
function you set should take a user ID (a unicode) and return a user
object, or None if the user does not exist.
Which would mean adjusting your user_loader to be something like:
#login_manager.user_loader
def get_user(user_id):
try:
return User.query.get(int(user_id))
except:
return None
Also, you have an error here, which is likely the direct cause of the error:
login_manager = login_message_category = 'info'
So your taking your login_manager and replacing it with a string with the contents 'info'. So later when your app tries to access login_manager.user_loader it's failing, because a string 'info' doesn't have a user_loader method.
Changing it to the below should fix the error. Though the other issues addressed above also need to be implemented.
login_manager.login_message_category = 'info'
You have used the login_manager = LoginManager(app) you are creating an object along with the configuration. Insider of that create an object first and configure the object in 2 steps.
login_manager = LoginManager()
login_manager.init_app(app)
for more reference please check the link here[https://flask-login.readthedocs.io/en/latest/]
you may need to update in your init.py file.
My problem:
I'm having trouble with a Flask application when it comes to specifying the return type of a function that calls on jsonify() in the return. Flask's jsonify is ultimately returning a current_app.response_class. However, by specifying this type of return in the signature, I get an error.
The error:
Traceback (most recent call last):
File "wsgi.py", line 1, in <module>
from app import app as application
File "./app.py", line 94, in <module>
def handle_msg_request() -> current_app.response_class:
File "/usr/local/lib/python3.7/site-packages/werkzeug/local.py", line 348, in __getattr__
return getattr(self._get_current_object(), name)
File "/usr/local/lib/python3.7/site-packages/werkzeug/local.py", line 307, in _get_current_object
return self.__local()
File "/usr/local/lib/python3.7/site-packages/flask/globals.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.
The offending code:
from flask import Flask, render_template, request, jsonify, send_from_directory, current_app
#app.route("/requestmessages", methods=['POST'])
def handle_msg_request() -> current_app.response_class:
last_id = int(request.form['lastId'])
data = get_all_chat_dict(min=last_id)
if len(data) == 0:
return jsonify(hasNewData=False)
return jsonify(hasNewData=True, dataRows=data)
Related/Similar issue:
I saw how this question had been solved by using with for the context, but I'm not quite sure how I'd apply that here, since I'm just trying to specify the return type for a function.
How can I go about specifying the return type in my signature when this type appears to be intertwined with the application's context?
Well, I am writing a Flask project, but when I tried to python manage.py
The traceback told me that:
Traceback (most recent call last):
File "manage.py", line 5, in <module>
from app import db,create_app
File "/home/humbert/2017-sharing-backend/sharing/app/__init__.py", line 42, in <module>
app.register_blueprint(main_blueprint, url_prefix='/main')
File "/home/humbert/venv/local/lib/python2.7/site-packages/flask/app.py", line 64, in wrapper_func
return f(self, *args, **kwargs)
File "/home/humbert/venv/local/lib/python2.7/site-packages/flask/app.py", line 951, in register_blueprint
blueprint.register(self, options, first_registration)
File "/home/humbert/venv/local/lib/python2.7/site-packages/flask/blueprints.py", line 154, in register
deferred(state)
File "/home/humbert/venv/local/lib/python2.7/site-packages/flask/blueprints.py", line 173, in <lambda>
s.add_url_rule(rule, endpoint, view_func, **options))
File "/home/humbert/venv/local/lib/python2.7/site-packages/flask/blueprints.py", line 76, in add_url_rule
view_func, defaults=defaults, **options)
File "/home/humbert/venv/local/lib/python2.7/site-packages/flask/app.py", line 64, in wrapper_func
return f(self, *args, **kwargs)
File "/home/humbert/venv/local/lib/python2.7/site-packages/flask/app.py", line 1043, in add_url_rule
rule = self.url_rule_class(rule, methods=methods, **options)
TypeError: __init__() got an unexpected keyword argument 'method'
I think my manage.py is right,and I can't figure out the mistake.
The mistake part of __init__.py is that:
from .main import main as main_blueprint
app.register_blueprint(main_blueprint, url_prefix='/main')
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint, url_prefix="/auth")
from . import views
I really need some help, thanks!
I had a similar problem. In my code I had a line
#bp.route('/<init:id>/delete', method=('POST'))
The keyword method needs to be changed to methods(with an s)
I had encountered a similar problem in my code and just had to change the keyword "method" to "methods":
#app.route('/login', methods = ['GET', 'POST'])
Here is my code:
blueprint = Blueprint('client', __name__, template_folder='templates')
#blueprint.before_request
def load_session_from_cookie():
account = check_sso_cookie(request.cookies, for_view=False)
# if error occurred, return error
if 'message' in account:
session.pop('accountId', None)
return redirect(settings.LOGIN_URL)
if 'accountId' in session:
return redirect(url_for('home'))
elif 'accountId' in account:
session['accountId'] = account.get('accountId')
return redirect(url_for('home'))
else:
session.pop('accountId', None)
return redirect(settings.LOGIN_URL)
Excuse my ignorance, this is my first Flask app that deals with session management. The above code keeps returning the error of RuntimeError: working outside of request context.
Here is the stacktrace:
Traceback (most recent call last):
File "runserver.py", line 1, in <module>
from api import app
File "/Users/dmonsewicz/dev/autoresponders/api/__init__.py", line 13, in <module>
import client
File "/Users/dmonsewicz/dev/autoresponders/api/client/__init__.py", line 33, in <module>
#blueprint.before_request(load_session_from_cookie())
File "/Users/dmonsewicz/dev/autoresponders/api/client/__init__.py", line 16, in load_session_from_cookie
account = check_sso_cookie(request.cookies, for_view=False)
File "/Users/dmonsewicz/.virtualenvs/autoresponders-api/lib/python2.7/site-packages/werkzeug/local.py", line 338, in __getattr__
return getattr(self._get_current_object(), name)
File "/Users/dmonsewicz/.virtualenvs/autoresponders-api/lib/python2.7/site-packages/werkzeug/local.py", line 297, in _get_current_object
return self.__local()
File "/Users/dmonsewicz/.virtualenvs/autoresponders-api/lib/python2.7/site-packages/flask/globals.py", line 20, in _lookup_req_object
raise RuntimeError('working outside of request context')
Anyone else run into this issue?
You need to register the function, not the return value of the function:
blueprint.before_request(load_session_from_cookie)
Note, no # either. This passes the function object to the blueprint.before_request() registration method.
Your version instead first called the load_session_from_cookie function, and the time your module is loaded, there is no request yet, hence the exception.
The # decorator syntax is normally used before the function definition, and Python will automatically call it for you:
#blueprint.before_request
def load_session_from_cookie():
# ... your function ...
Note that this time we don't call it.
The latter form is the intended syntax, you only need to use the explicit form (the first) if you cannot apply the decorator at module load time (say, because blueprint is loaded dynamically later on, in a blueprint factory function or similar).
I'm trying to write a Google-Appengine app that will fail nicely when datastore writes are disabled
Currently my main() looks like this:
def main():
make_datastore_readonly()
try:
run_wsgi_app(application)
except CapabilityDisabledError:
run_wsgi_app(NoWrite)
If I set main to:
def main():
run_wsgi_app(application)
My app displays a traceback when the exception is raised.
If I set main to:
def main():
run_wsgi_app(NoWrite)
It will properly show my error message (although for every request).
Getting back to my modified version of main, this one:
def main():
make_datastore_readonly()
try:
run_wsgi_app(application)
except CapabilityDisabledError:
run_wsgi_app(NoWrite)
Instead of getting my error message, I still get a traceback that looks like this:
Traceback (most recent call last):
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/_webapp25.py", line 703, in __call__
handler.post(*groups)
File "/Users/kevin/Sche/main.py", line 232, in post
me.put();
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/db/__init__.py", line 1074, in put
return datastore.Put(self._entity, **kwargs)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/datastore.py", line 579, in Put
return PutAsync(entities, **kwargs).get_result()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/datastore.py", line 556, in PutAsync
return _GetConnection().async_put(config, entities, local_extra_hook)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/datastore/datastore_rpc.py", line 1553, in async_put
return make_put_call(base_req, pbs, extra_hook)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/datastore/datastore_rpc.py", line 1543, in make_put_call
self.__put_hook, user_data)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/datastore/datastore_rpc.py", line 1188, in make_rpc_call
rpc.make_call(method, request, response, get_result_hook, user_data)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/apiproxy_stub_map.py", line 519, in make_call
self.__service, method, request, response, self.__rpc)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/apiproxy_stub_map.py", line 207, in Call
function(service, call, request, response)
File "/Users/kevin/Sche/main.py", line 18, in hook
raise CapabilityDisabledError('Datastore is in read-only mode')
CapabilityDisabledError: Datastore is in read-only mode
So, my question is, why isn't the exception caught?
Edit:
This function is from this StackOverflow answer
def make_datastore_readonly():
"""Throw ReadOnlyError on put and delete operations."""
def hook(service, call, request, response):
assert(service == 'datastore_v3')
if call in ('Put', 'Delete'):
raise CapabilityDisabledError('Datastore is in read-only mode') //Line 18
apiproxy_stub_map.apiproxy.GetPreCallHooks().Push('readonly_datastore', hook, 'datastore_v3')
the main function only register this application. Therefore, the exception will not raise in the main function. Therefore the try ... catch statement won't work.
The way to handle this exception is defining a new RequestHandler. Then, all requests which want to have this feature should inherent from the new RequestHandler.
for example:
Class MyRequestHandler(RequestHandler):
def get(self):
try:
self.get_handler()
except CapabilityDisabledError:
pass
class MyRequest(MyRequestHandler):
def get_handler(self):
# ....
pass