How to stop Flask method from executing after hitting Page Reload - python-3.x

I have a basic HTML Form with file input that accepts multiple files. When the user clicks on Upload button I want to print numbers till 10**9 on my terminal.Say while execution of loop the user clicks refresh/reload, I want to stop current loop and redirect to index page. But even after hitting refresh the loop continues to execute.
index.html
<form method="POST" action="upload" enctype="multipart/form-data" class="uploader">
<input id="file-upload" type="file" name="fileUpload" accept=".ent,.pdb" multiple/>
<input type="submit" class="btn btn-primary" value="Upload"/>
</form>
app.py
from flask import Flask, render_template, redirect
UPLOAD_FOLDER = 'uploads'
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
#app.route("/")
def index():
return render_template("index.html")
#app.route('/upload',methods = ['GET','POST'])
def upload_file():
t=0
while(t<10**9):
print(t)
t+=1
return redirect('/')
if __name__ == '__main__':
app.run(debug=True)

Related

can not call function into wtforms radio field

I am trying to call a regular function into RadioField - choices[()].
when i select a radio button on my web page and click submit button, i should get the result from from function. my function says to print("Hi").
currently it print's the data on given value like 'value_one' when i select description.
So, i need a way to do call function to choices[('')].
below is my code
from flask import Flask, render_template
from flask_wtf import Form
from wtforms import RadioField, SubmitField
app = Flask(__name__)
app.config.from_object(__name__)
app.secret_key = 'password'
def print_1():
print("Hi")
class SimpleForm(Form):
example = RadioField('Label', choices=[('value_one','description'),('value_two','whatever')])
#app.route('/',methods=['post','get'])
def hello_world():
form = SimpleForm()
if form.validate_on_submit():
print(form.example.data)
else:
print(form.errors)
return render_template('form.html',form=form)
if __name__ == '__main__':
app.run(debug=True)
Below is my html code:
<form method="post">
{{ form.hidden_tag() }}
{{ form.example }}
<input type="submit" value="submit">
</form>

Field validation in WTF Forms Flask, redirect method

I am trying to create my first Flask web application and found the following problem, I have two pages, the first page should take players names and give the names to the next page, but unfortunately name validation does not work due to some reason, I can keep the required fields empty and go to next page with empty names fields.
Flask code:
class ChooseName(FlaskForm):
first_player_name = StringField("Choose first player name: ", [DataRequired()])
second_player_name = StringField("Choose second player name: ", [DataRequired()])
button = SubmitField("Confirm")
#app.route('/')
def index():
form = ChooseName()
if form.validate_on_submit():
return redirect(url_for('mega'))
return render_template('TIC_TAC_TOE_index.html', form=form)
#app.route('/game_page', methods=["GET", "POST"])
def mega():
player1 = request.args.get('first_player_name')
player2 = request.args.get('second_player_name')
......
return render_template('mega.html', form=form, error=error, x=x,
turn=turn,tornado=tornado, renew=renew, player1=player1,player2=player2)
HTML template:
<form action="{{url_for('mega')}}" method="get">
{{ form.hidden_tag() }}
<h4>Please choose players names!</h4>
{{form.first_player_name.label}} {{form.first_player_name}} <br> <br>
{{form.second_player_name.label}} {{form.second_player_name}} <br> <br>
{{form.button}} <br> <br>
</form>
Well looking at your function Mega(), you're not returning anything on the next page. You're just accepting the input but aren't returning it in any form.
from wtforms import Form, StringField, validators, SubmitField
from flask_wtf import FlaskForm
from flask import Flask, render_template, request
class ChooseName(FlaskForm):
first_player_name = StringField("Choose first player name: ", [validators.DataRequired()])
second_player_name = StringField("Choose second player name: ", [validators.DataRequired()])
button = SubmitField("Confirm")
app = Flask(__name__)
app.config['SECRET_KEY'] = "IT_IS_SECRET"
#app.route('/')
def index():
form = ChooseName()
if form.validate_on_submit():
return redirect(url_for('mega'))
return render_template('TIC_TAC_TOE_index.html', form=form)
#app.route('/game_page', methods=["GET", "POST"])
def mega():
player1 = request.args.get('first_player_name')
player2 = request.args.get('second_player_name')
return player1 + ' ' + player2
if __name__ == '__main__':
app.run(port=5000,debug=True)
Try to run this code, I hope this helps. :-)
This is because your action is pointing to the mega view, so the code from index if form.validate_on_submit(): is not being executed.
You should change the action attribute and method in your form. The code should be as follows:
HTML template:
<form action="" method="post">
{{ form.hidden_tag() }}
<h4>Please choose players names!</h4>
{{form.first_player_name.label}} {{form.first_player_name}} <br> <br>
{{form.second_player_name.label}} {{form.second_player_name}} <br> <br>
{{form.button}} <br> <br>
</form>
Views:
from flask import session
#app.route('/')
def index():
form = ChooseName()
if form.validate_on_submit():
session['first_player_name'] = form.first_player_name.data
session['second_player_name'] = form.second_player_name.data
return redirect(url_for('mega'))
return render_template('TIC_TAC_TOE_index.html', form=form)
#app.route('/game_page', methods=["GET", "POST"])
def mega():
player1 = session.pop('first_player_name')
player2 = session.pop('second_player_name')
......
return render_template('mega.html', form=form, error=error, x=x,
turn=turn,tornado=tornado, renew=renew, player1=player1,player2=player2)
You can learn more about WTForms here https://j2logo.com/tutorial-flask-leccion-3-formularios-wtforms/

How to redirect users to the required html page only after successful login (Flask Python App)?

I am trying to set up login page before accessing any other page. So as of now the code is working fine but if I access '/home' its taking directly to that page without login required page.
I tried to understand online solutions like login-required with SQLAlchemy but nothing seems working and I got totally lost. This does not require login-required I guess.
Here's my code:
from dbscriptdeploy import dbupdate
from flask.templating import render_template
from flask import Flask, request, url_for, redirect
DBupdate = dbupdate()
app = Flask(__name__) #create the Flask app
#app.route('/success')
def deploy_success():
return render_template("success.html")
def deploy_script(sql):
res = DBupdate.dbvalues_get(sql)
return res
#app.route('/', methods=['GET', 'POST'])
def login_page():
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('form_example'))
return render_template('login.html', error=error)
#app.route('/home', methods=['GET', 'POST'])
def form_example():
res = None
error = ''
try:
if request.method == 'POST':
sql = request.form.get('sql')
res = deploy_script(sql)
if res:
return redirect(url_for('deploy_success'))
else:
error = "*Invalid Value. Please try again."
return render_template('home.html', error=error)
except Exception as e:
return render_template('home.html', error=error)
if __name__ == '__main__':
app.run(debug=True) #run app in debug mode on port 5000
Login.html Code:
<html>
<head>
<title>Flask Intro - login page</title>
</head>
<body>
<div class="container">
<h1>Please login</h1>
<br>
<form action="" method="post">
<input type="text" placeholder="Username" name="username" value="{{
request.form.username }}">
<input type="password" placeholder="Password" name="password" value="{{
request.form.password }}">
<input class="btn btn-default" type="submit" value="Login">
</form>
{% if error %}
<p class="error"><strong>Error:</strong> {{ error }}
{% endif %}
</div>
</body>
</html>
So what I expect is after successful login only then they should be directed to \home page else they should be directed again to login page.
If I were you, I'd use flask-login. However, if you want to develop a simple solution by your own, you should save some var in the user's session.
Also in your login method there is a bug. I'd do:
from flask import session
#app.route('/', methods=['GET', 'POST'])
def login_page():
error = None
if request.method == 'POST':
if request.form['username'] == 'admin' and request.form['password'] == 'admin':
session['admin'] = request.form['username']
return redirect(url_for('form_example'))
else:
error = 'Invalid Credentials. Please try again.'
return render_template('login.html', error=error)
Then, in your form_example view you should check that admin is in session, else you can redirect to your login view:
#app.route('/home', methods=['GET', 'POST'])
def form_example():
if 'admin' not in session:
return redirect(url_for('login_page'))
else:
# Your code here
If you really want to go down the path of developing your own login/authentication solution, check out the documentation for flash_message
http://flask.pocoo.org/docs/1.0/patterns/flashing/. This tutorial has the exact problem you're tackling.
The re-routing of a successful login attempt occurs with the redirect call
return redirect(url_for('homepage'))

How do I save file in different directory upon clicking submit using flask?

I have a simple python file that sends a file from a local directory to be displayed in html. And, when the user clicks submit, I want to save this file to a different directory, but I can't seem to make this happen.
Here's my code:
Uploader.py
from __future__ import print_function
from random import choice
from flask import Flask, request, redirect, url_for, flash, render_template, abort, send_file, session
from werkzeug.utils import secure_filename
from flask import send_from_directory
import sys, os
app = Flask(__name__)
#app.route('/')
def init(file_Idx=0):
files = os.listdir(DOWNLOAD_FOLDER)
filePath = os.path.join(DOWNLOAD_FOLDER, files[file_Idx])
return render_template('files.html', file=filePath)
#app.route('/upload', methods=['POST'])
def upload_file():
file = request.files['image'] #Failing here!!!
f = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
file.save(f)
return render_template('files.html')
files.html
<form action="/upload" method="post" enctype="multipart/form-data">
<img src="{{file}}"/>
<input type=submit name="image">
</form>
Right now the image is displaying, but I can't seem to pass the file to upload_file() to save it in the upload_folder. How can I make this work?
Try this, you can define your desired path in it.
You can Edit the line
file.save(os.path.join("/tmp/", filename))
and place your desired path in it.
from flask import Flask, render_template, request
from werkzeug import secure_filename
app = Flask(__name__)
#app.route('/upload')
def upload_file():
return render_template('upload.html')
#app.route('/uploader', methods = ['GET', 'POST'])
def upload_file():
if request.method == 'POST':
file = request.files['file']
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join("/tmp/", filename))
if __name__ == '__main__':
app.run(debug = True)
and HTML code for that
<form id="package_form" action="" method="POST">
<div>
<p>Upload Packages:</p>
<p><input id="upload_button" type="file" class="btn btn-default btn-xs" name="file"></p>
<p><input id="submit_button" type="submit" class="btn btn-success" value="Upload">
</div>

Unable to Stop Python from Flask GUI

I am trying to create a GUI where I will have 2 buttons. Start button will trigger my python script and display the moving graph. When I press the stop button, the graph should exit and python should stop.
when I click on start button, I am getting the desired result. But it goes to infinite loop and the stop button does not exit the code.Clicking on stop button does not take the code to the decorator and my function stop() is not executed.
Below is the snippet :
from flask import Flask, request, flash, url_for, redirect, render_template, session
from flask import render_template
import numpy as np
import matplotlib.pyplot as plt
import io
import threading
import base64
from IPython import get_ipython
from sys import exit
app = Flask(__name__)
#app.route('/')
def home():
return render_template('home.html')
#app.route('/plot' , methods = ['GET', 'POST'])
def build_plot():
img = io.BytesIO()
global running
x = np.linspace(-180, 180,1000)
y = np.sin(x)
global j
fig, ax = plt.subplots()
plt.plot(x[0:200], y[0:200])
#plt.plot(x,y)
for i in range(200, len(y)):
plt.scatter(x[i], y[i])
plt.pause(0.0005)
return(get_ipython().run_line_magic('matplotlib', 'inline'))
#app.route('/stop' , methods = ['GET', 'POST'])
def stop():
#stop_ind='N'
#exit()
return render_template('home.html')
if __name__ == '__main__':
app.debug = True
app.run()
The function where I want to exit is not getting called.
Below is my HTML :
<!DOCTYPE html>
<html>
<title>HOME PAGE..</title>
<body>
<h1>Home Page..!!</h1>
<form action="/plot" method="POST">
<input type="number" name="Number" ><br>
<br>
<input type="submit" value="Start" >
</form>
<form action="/stop" method="POST">
<br>
<input type="submit" value="Stop" >
</form>
</body>
</html>
</form>
</body>
</html>
Your Flask app can not respond to your input because it is busy in your loop.
You will need to put the calculation of your results in a separate Thread or Coroutine in order to stop it from blocking your main Flask Thread.
Also you can use Websockets to communicate with your Frontend. Have a look at Flask-SocketIO. It uses Websockets to communicate between Flask and your Frontend.

Resources