I am developing an app using Flask, In the app, user upload files to the server, before uploading I used to check that user is authenticated or not. If the user is authenticated, then the uploading file is saved in the server otherwise flask redirected to home page.
Code -
In app.py -
#login_required
#app.route('/home')
def home():
if current_user.Is_Authenticated:
return redirect(url_for('post1'))
else:
return render_template('post2.html')
#app.route('/upload', methods=['POST'])
def upload():
if current_user.Is_Authenticated:
user = current_user.Email
flag = True
else:
print("Current User is not Authenticated")
flag = False
if(flag):
if(request.method == "POST"):
if(request.files['myfile']):
myfile = request.files["myfile"]
sfname = os.path.join(os.getcwd(), 'static', str(secure_filename(myfile.filename)))
myfile.save(sfname)
return render_template('post.html')
else:
return redirect(url_for('home'))
When, I am testing the app, I found that, before authenticated, a user upload files with larger than 10MB, it shows "Site is not reachable". If it is small sized file, then flask redirected to home page, correctly.
how to solve this, why flask is not working when the uploading file size is larger than 10Mb, Thank you
In Flask you can limit the file size using MAX_CONTENT_LENGTH while configuring your app.
If the file size is greater than MAX_CONTENT_LENGTH you get this kind of errors Please refer to this (for error messages, for different browser and there are also solutions as well)
Increase this MAX_CONTENT_LENGTH to handle large file size
or use the below code to handle large file error
#app.errorhandler(413)
def request_entity_too_large(error):
return 'File Too Large', 413
Happy coding!
Related
Hello,
I am trying to handle errors when uploading a file with a disallowed filetype or when submiting without selecting any file.
All I get is "flask_uploads.exceptions.UploadNotAllowed" and on the web page "Internal Server Error". I want to flash an error message but have no idea how to handle the error. I googled and I read the documentation but I couldn't find a way.
Everything works fine when selecting and submiting the right type of file/files(in this case IMAGES).
Thank you!
if request.method == 'POST':
if form.validate_on_submit() and 'artwork' in request.files:
art = form.artwork.data
this_artf = art_f+'/'+str(order_no_art)
app.config['UPLOADED_IMAGES_DEST'] = this_artf
images = UploadSet('images', IMAGES)
configure_uploads(app, images)
for image in art:
images.save(image)
As you said, you have looked in the documentation...
I just enhanced the example shown at https://github.com/jugmac00/flask-reuploaded with handling the mentioned UploadNotAllowed exception.
Be sure to not forget to import the exception first!
...
from flask_uploads.exceptions import UploadNotAllowed
...
#app.route("/", methods=['GET', 'POST'])
def upload():
if request.method == 'POST' and 'photo' in request.files:
try:
photos.save(request.files['photo'])
flash("Photo saved successfully.")
return render_template('upload.html')
except UploadNotAllowed:
flash("File type not allowed!")
return render_template('upload.html')
return render_template('upload.html')
This is a generic answer, but I am positive you can apply it to your case.
By the way, I saw you configured the app within the request handling:
if request.method == 'POST':
if form.validate_on_submit() and 'artwork' in request.files:
art = form.artwork.data
this_artf = art_f+'/'+str(order_no_art)
app.config['UPLOADED_IMAGES_DEST'] = this_artf
images = UploadSet('images', IMAGES)
configure_uploads(app, images)
While this currently works, this is not the way it is supposed to do.
It is about these lines...
app.config['UPLOADED_IMAGES_DEST'] = this_artf
images = UploadSet('images', IMAGES)
configure_uploads(app, images)
You have to move those lines outside the request context, e.g. at the top of your module or in your application factory.
Disclaimer: I am the maintainer of Flask-Reuploaded.
Handle flask_uploads.exceptions.UploadNotAllowed exception when invoking save method on instance of UploadSet.
from flask_uploads.exceptions import UploadNotAllowed
from flask import flash # make sure to configure secret key for your app
#....
error_files = []
for image in art:
try:
images.save(image)
except flask_uploads.exceptions.UploadNotAllowed as err:
error_files.append(image.filename)
continue
flash(error_files, 'error')
You could then, present the files in the rendered template by getting the flashed messages.
I'm currently building my very first own project, a web application with Flask which interacts with the Spotify API. The project is as good as ready after extensive testing locally and on a Heroku staging environment. However I'm currently experiencing a small login 'bug' I can't seem to wrap my head around.
When clicking a Login button, the application sends a request to the Spotify API, which sends back an authorization code upon confirmation of the user to read his data. This confirmation will result in the user being redirected to the '/profile route' of the web app. The flow of the login process so far on different environments:
Locally: process has always ran smoothly (read: click the Login button once which redirects the user to /profile route)
Staging (Heroku): clicking the login button generates the correct request to the Spotify API. However, when clicking it for the for the 1st time I get redirected to the login page (due to my login_required Flask decorator). When clicking it for the 2nd time it also generates the correct request and correctly sends the user to the '/profile route'.
I can see in the server logs clicking the login button for the 1st time generates the correct request. But it seems as if the validation by the login_required decorator of the '/profile route' goes 'too fast'? Or does this have something to do with caching? Because I'm also able to reproduce the bug (sometimes) by removing cache and hard refreshing the page.
I recently added a SECRET_KEY to session and changed the SESSION_PERMANENT from False to True but I don't think this is causing the issue? Some of the code I think might be causing this little bug:
# Ensure responses aren't cached
#app.after_request
def after_request(response):
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
response.headers["Expires"] = 0
response.headers["Pragma"] = "no-cache"
return response
# Configure session to use filesystem
app.config['SECRET_KEY'] = os.urandom(64)
app.config["SESSION_FILE_DIR"] = mkdtemp()
app.config["SESSION_PERMANENT"] = True
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
def login_required(f):
"""
Decorate routes to require login:
http://flask.pocoo.org/docs/1.0/patterns/viewdecorators/
"""
#wraps(f)
def decorated_function(*args, **kwargs):
if session.get("authorization_header") is None:
return redirect(url_for('login'))
return f(*args, **kwargs)
return decorated_function
#app.route("/")
def index():
""" Shows landing page """
if session.get("authorization_header") is not None:
return redirect(url_for('profile'))
return render_template("index.html")
#app.route("/login")
def login():
""" Shows login page """
if session.get("authorization_header") is not None:
return redirect(url_for('profile'))
return render_template("login.html")
#app.route("/logout")
#helpers.login_required
def logout():
""" Logs user out """
# Forget any user_id
session.clear()
# Redirect user to login form
return redirect(url_for("index"))
#app.route("/profile")
#helpers.login_required
def profile():
""" Shows overview of user's Spotfy profile """
Not sure if this is your issue, but could cause some weird behaviour...
app.config['SECRET_KEY'] = os.urandom(64) This will result in a different secret key being set on each heroku dyno (if running multiple workers; the default is 2 for syncronous workers) as that random string is generated dynamically at worker boot time.
As a side note, os.urandom isn't for generating keys. Instead use the secrets module, and set the resulting string as a config var in heroku CLI and load it in your app with:
import os
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')
I am trying to set up a POC website in Flask\python to play around with some APIs. I have made a simple login page that redirects to /loggedin. But /loggedin is also accesible by just writing https://mysite/loggedin.html. Is there an easy way to prevent this that does not involve using something like flask-login? I don't want to spend time setting up an SQL user base and such, as I will be the only user of the application.
app = Flask(__name__)
#app.route("/")
def home():
return render_template("home.html")
#app.route("/loggedin")
def innsiden():
return render_template("loggedin.html")
#app.route("/login", methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or request.form['password'] != 'admin':
error = 'Invalid Credentials. Please try again.'
else:
return redirect(url_for('loggedin'))
return render_template('login.html', error=error)
In flask you can maintain on the server "session" information.
A simple method might be to
When user logs in with the correct password, add their username to the session data
When a logged in user visits a "secure" page, flask checks to see if their user id is in the sesson data if 'username' in session:. If it is, they are directed to the correct page, if not they are directed to a log in page
When the user logs out, their user name is removed from the list.
A version of this recipe is described at https://www.tutorialspoint.com/flask/flask_sessions.htm
I am actually creating an app with Flask and I am encountering issues regarding my routing.
My situation is simple: The user enters a token to authenticate himself. Once he clicks on authenticate, an angular HTTP request uses POST to send his token to a Python server. There, if he is granted access, the home page is displayed using render_template; otherwise the login keeps still.
However, when the user authenticates himself, I see on my command line that the POST was successful, the authentication was a success but the page just stuck on login and does not redirect to home page as if the second render_template does not work. Please Help!
#app.route('/')
def index():
if not session.get('logged_in'):
return render_template('auth.html') # this is ok.
else:
return render_template('index.html') # this does not work
#app.route('/login', methods=['POST','GET'])
def login():
tok = request.form['token']
if (check_token(tok) == "pass"): # check_token is a function I've implemented
# to check if token is ok=pass, ko=fail
session['logged_in'] = True
else:
flash("wrong token")
return index()
Your login handler shouldn't call index directly. It should return a redirect to the index.
return redirect('/')
or better:
return redirect(url_for('index'))
I was thinking of the following.
#app.route('/')
def index():
if not session.get('logged_in'):
return return redirect(url_for('login'))
else:
return render_template('index.html')
#app.route('/login', methods=['POST','GET'])
def login():
if request.method = "POST":
tok = request.form['token']
if (check_token(tok) == "pass"):
session['logged_in'] = True
return redirect(url_for('index'))
else:
flash("wrong token")
return render_template("login.html")
I have used Angular JS in my app to send requests to my flask server and i realised that my client side angular JS had difficulties in rendering page as it was just expecting a response.
I first tried to do.. document.write('response.data') and it did display my home page but my scripts attached on my html page stopped working.
Second try, I tried to reload the page after receiving the response in my client and it works well. I don't know if it's the best way to do but it does work.
I'm very new to Flask and don't have much experience in Python.
As required by my project, I need to do certain processing in the backend (through Python script) using the input given by user and show the end results to the user afterwards, whenever he logs in.
A little description as to what my project does - Whenever the user logs in, he/she enters any Twitter handle in html form and the python script gets certain details regarding that handle (number of similar users, followers, no. of tweets, etc.) and this process takes approximately 5-6 minutes. Currently, I am processing and storing all this data in CSVs and then showing the results in HTML.
Now, I don't want my user to wait for those 5-6 minutes to view the results and thus, want the processed results to be stored in the database so that the user can view them whenever he logs in, say even after 1-2 hours.
How should I implement this in Flask, by using SQLAlchemy? I already have made the database for login screen as below, but don't know how to go about this.
from flask import Flask, render_template, session
from sqlalchemy import create_engine
engine = create_engine('sqlite:///tutorial.db', echo=True)
app = Flask(__name__)
#app.route('/')
def home():
if not session.get('logged_in'):
return render_template('login.html')
else:
return render_template('test.html')
#app.route('/login', methods=['POST'])
def do_admin_login():
error = False
POST_USERNAME = str(request.form['username'])
POST_PASSWORD = str(request.form['password'])
Session = sessionmaker(bind=engine)
s = Session()
query = s.query(User).filter(User.username.in_([POST_USERNAME]),
User.password.in_([POST_PASSWORD]))
data = query.first()
if data:
session['logged_in'] = True
flash('Login success')
return render_template('test.html')
else:
flash('Login failed!')
return render_template('login.html',error=True)
#app.route("/logout")
def logout():
session['logged_in'] = False
return home()
The test.html mentioned above takes the twitter handle as input from the user through html form.