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.
Related
#app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
# Login and validate the user.
# user should be an instance of your `User` class
login_user(user)
flask.flash('Logged in successfully.')
return flask.render_template('login.html', form=form)
The above is my attempt at this. How can one send multiple login requests at the same time? Additionally, how can one check how the webapp behaves
I'm not totally sure I understand your question, but your flask app will behave normally as expected when multiple users login simultaneously unless you are executing a huge script. Also, you have no need for the 'flask.' prefix which precedes flash and render_template.
Hello am new at using flask and I have been trying to figure out how to restrict some web pages unless logged in. I tried flask decorators I tried flask decorators but I couldn't understand it so I tried using flask principal which am able to get it running but still cannot be able to stop the access to that webpage.
Code Description
from flask_principal import Permission, RoleNeed
# create permission with a single Need, in this case a RoleNeed
user_permission = Permission(RoleNeed('User'))
#app.route('/home')
def home_page():
return render_template('home.html')
#app.route('/user')
#user_permission.require()
def do_user_index():
return Response('Only if you are a user')
#app.route('/employee')
def employee_page():
user = User.query.all()
return render_template('employee.html', user=user)
def do_employee_page():
with user_permission.require():
return redirect(url_for('login_page'))
You can use session:
First thing we gonna do is create a session at the moment of login:
#app.route(#route that you gonna use to login data verify)
def login():
#login data verification
flask.session["user data"] = #Data you want to use to identify the user
#the next step that you wanna do
Now we gonna verify the session data in the pages, if the user are log in they gonna have their data in flask.session and if not, they not going to have the data in session.
#app.route('/user')
def do_user_index():
if "user data" not in flask.session:
#Redirect to the login page
return Response('Only if you are a user')
You can consult the documentation to learn more about the how to use session.
https://flask.palletsprojects.com/en/2.0.x/quickstart/#sessions
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
Hi I am new to flask and I am trying to create a simple login functionality. Users fill out their username and password (which at this point needs to match the username and password I hardcoded) and if their credentials are approved they are taken to their profile page. The profile page should show the message Hello followed by the username.
The validation is working just fine and the user is taken to the profile page but I can't pass the username from the form (login.html) to the template "profile.html".
Below follows the code. I am sending the code that works but there is no tentative to pass the username.
Thank you!
from flask import *
SECRET_KEY = "super secret"
app = Flask(__name__)
app.config.from_object(__name__)
#app.route('/')
def index():
return render_template('login.html')
#app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] == 'user' and request.form['password'] == 'pass':
session['loggedin'] = True
return redirect(url_for('profile'))
else:
error="Invalid credentials. Please try again."
return render_template('login.html', error=error)
#app.route('/profile')
def profile():
return render_template('profile.html')
#app.route('/logout')
def logout():
session.pop('loggedin', None)
return redirect(url_for('login'))
if __name__ == '__main__':
app.run(debug=True)
I think you miss the point of your hard work login page.
What about the next page the user will choose to visit? Will you send the username value again? of course not..
I suggest you to define a global var(session? DB data?) that contain the current-logged-in-user-data, so you can use all user's data, not only his username(age?posts? etc..)
One last thing, i use flask-login, i really like it, it simple mange my login session/views and guess what? there is current_user with the current-logged-in-user-data :)
Flask-login summery:
Flask-Login provides user session management for Flask.
It handles the common tasks of logging in, logging out, and remembering your users’ sessions over extended periods of time.
Why not make use of flask's many useful modules? They make flask an attractive microframework for speedy web development.
Flask-login, as stated above, streamlines authentication processes and manages sessions. Flask sessions also automatically stores session data for logged-in users. This allows you to implement a "Remember Me" feature in your login form.
Also, for security purposes, you would want to decorate some of your functions with #login_required, which is part of the flask-login module. This makes sure that the user is automatically redirected to the login page if he or she is not logged in already.
Here is an example of an index function that implements this:
from flask import render_template, session
from flask.ext.login import login_required
#app.route('/')
#login_required
def index():
return render_template("index.html")
You could also use flask.ext.openidto make authentication even more convenient.