How can I make a non-permanent session in Flask - python

I'm learning flask and am trying to associate some randomly generated data with each session.
I use the approach from this answer to set session.permanent to False, but closing the browser, then reopening it at going back to the page still displays the same code.
MWE:
from flask import Flask, session
import numpy as np
app = Flask(__name__)
app.secret_key = "supersecretkey"
#app.before_request
def make_session_permanent():
session.permanent = False
#app.route('/')
def index():
if 'id' not in session:
random_id = "".join(np.random.choice(list("abcdefg123"), 16))
session["id"] = random_id
return session['id']
if __name__ == '__main__':
app.run(debug=True)
Update: Based on this answer someone recommended to use socketio to notice disconnects. This also makes no difference, i.e. closing the browser, reopening it, and going to 127.0.0.1:5000 gives the same number as before closing. An updated MWE using this is below:
from flask import Flask, session
from flask_socketio import SocketIO
import numpy as np
app = Flask(__name__)
app.secret_key = "supersecretkey"
#app.before_request
def make_session_permanent():
session.permanent = False
#app.route('/')
def index():
if 'id' not in session:
random_id = "".join(np.random.choice(list("abcdefg123"), 16))
session["id"] = random_id
return session['id']
socketio = SocketIO(app)
#socketio.on('disconnect')
def disconnect_user():
session.pop('id', None)
if __name__ == '__main__':
app.run(debug=True)

# Instantiate a new web application called `app`,
# with `__name__` representing the current file
app = Flask(__name__)
app.config["SESSION_PERMANENT"] = False

Related

How to connect Flask REST API to HTML page

I have created an REST-API using flask so now , I don't know how to connect it with HTML page .
Hear is my app.py code of rest-api
from blocklist import blocklist
import re
from flask import Flask, jsonify
from flask_restful import Api
from flask_jwt_extended import JWTManager
import redis
from db import db
from jwt import PyJWKClient
from resources.user import UserRegister, User, UserLogin, TokenRefresh, UserLogout
from resources.item import Item, ItemList
from resources.store import Store, StoreList
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///data.db"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["PROPAGATE_EXCEPTIONS"] = True
app.config["JWT_BLACKLIST_ENABLED"] = True
app.secret_key = "jose"
api = Api(app)
#app.before_first_request
def create_tables():
db.create_all()
jwt = JWTManager(app) # not creating an auth
jwt_redis_blocklist = redis.StrictRedis(
host="localhost", port=5000, decode_responses=True
)
#jwt.expired_token_loader
def check_if_token_is_revoked(jwt_header, jwt_payload):
jti = jwt_payload["jti"]
token_in_redis = jwt_redis_blocklist.get(jti)
return token_in_redis is not None
#jwt.token_in_blocklist_loader
def check_if_token_in_blacklist(jwt_header, jwt_payload):
return jwt_payload["jti"] in blocklist
api.add_resource(Store, "/store/<string:name>")
api.add_resource(StoreList, "/stores")
api.add_resource(Item, "/item/<string:name>")
api.add_resource(ItemList, "/items")
api.add_resource(UserRegister, "/register")
api.add_resource(User, "/user/<int:user_id>")
api.add_resource(UserLogin, "/login")
api.add_resource(UserLogout, "/logout")
api.add_resource(TokenRefresh, "/refresh")
if __name__ == "__main__":
db.init_app(app)
app.run(port=5000, debug=True)
I have no idea how do I fetch data from API and show it to HTML page
#app.route("/")
def page_home():
# YOUR CODE HERE
return flask.render_template('home.html')
like above you can render the html file

Why do I lose the session information on redirect in Flask app?

I was following one of cs50's lectures and writing the same code in vscode as in the lecture. For some reason it works in the course's ide but when it is in vscode on my PC the session forgets the input after redirection. Where is the problem and Is it possible to fix it?
from flask import Flask, render_template, request, redirect, session
from flask_session import Session
app = Flask(__name__)
app.config['SESSION_PERMANENT'] = False
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SECRET_KEY'] = 'randomkey'
Session(app)
#app.route('/')
def tasks():
if 'todos' not in session:
session['todos'] = []
return render_template('tasks.html', todos=session['todos'])
#app.route('/add', methods=["GET", "POST"])
def add():
if request.method == "GET":
return render_template('add.html')
else:
todo = request.form.get('task')
session['todos'].append(todo)
return redirect('/')

session variables in flask keep changing

I have a very basic flask application that I have deployed to Heroku. I am trying to define a variable that I can change when a specific function is executed. For example, if I have a variable logged_in=True, I want to be able to change it to logged_in=False when the route #app.route('/logout') is executed. Here is the code:
import os
from flask import Flask, session, request, redirect, url_for, flash, g
from flask import render_template
from flask_session import Session
app = Flask(__name__)
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
# Configure session to use filesystem
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
app.config['logged_in']=True
Session(app)
# Redirect to /login route
#app.route('/')
def index():
return redirect(url_for("login"))
# Open main login page
#app.route("/login", methods=["POST","GET"])
def login():
return render_template("login.html")
# Verify login credentials
#app.route("/login_check",methods=["POST"])
def login_check():
return redirect(url_for("main_page"),code=307) if app.config['logged_in']==True else render_template("not_logged_in.html")
#app.route("/main_page", methods=["POST"])
def main_page():
return render_template("main_page.html",name="Main page")
#app.route("/log_out", methods=["POST"])
def log_out():
app.config['logged_in']=False
return redirect(url_for("login"))
if __name__ == '__main__':
app.run(debug=True)
When I launch the app locally, the value of logged_in is set to False when logout is executed and does not change if login is triggered again. However, when I deploy the app to Heroku, the value of logged_in goes back True when login is triggered again (it's weird, the value changes sometimes, but not always).
How can I set the value of logged_in so that it does not change until I update it with a function? I tried to use session.config['logged_in']instead of app.config['logged_in'], but I had the same issue. Ideally, I want the value to be unique for each session.
Thank you
If you want to store one value to each session. No sql like redis is recommendation.
import os
from flask import Flask, session, request, redirect, url_for, flash, g
from flask import render_template
from flask_session import Session
import redis
app = Flask(__name__)
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = redis.from_url('127.0.0.1:6379')
# Configure session to use filesystem
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
app.config['logged_in']=True
Session(app)
# Redirect to /login route
#app.route('/')
def index():
return redirect(url_for("login"))
# Open main login page
#app.route("/login", methods=["POST","GET"])
def login():
return render_template("login.html")
# Verify login credentials
#app.route("/login_check",methods=["POST"])
def login_check():
return redirect(url_for("main_page"),code=307) if app.config['logged_in']==True else render_template("not_logged_in.html")
#app.route("/main_page", methods=["POST"])
def main_page():
return render_template("main_page.html",name="Main page")
#app.route("/log_out", methods=["POST"])
def log_out():
session['key'] = 'False'
return redirect(url_for("login"))
if __name__ == '__main__':
app.run(debug=True)

Key Error in Flask Sessions

So I have been using sessions to pass data from one decorator to another. But now every time I make a new session variable, I get a KeyError from page to page. Meaning, I had a session error from my third to fourth page; but I had the same issue adding a new session variable from my second to third page even though I have four other session variables that give me no error.
My code is similar to the one #laila posted below:
from flask import Flask, render_template
from flask import request, session, url_for,abort,redirect
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
#app.route('/'):
def first():
session['this_one']='hello'
render('template.html')
#app.route('/second')
def second():
it=session['this_one']
render('other_page.html')
if __name__ == '__main__':
app.run(debug=True)
it seems like the code has some syntax error.Please try the code below, it should be ok:
from flask import Flask, render_template
from flask import request, session, url_for, abort, redirect
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
#app.route('/')
def first():
session['this_one'] = 'hello'
return render_template('template.html')
#app.route('/second')
def second():
it = session.get('this_one', 'not found')
return render_template('other_page.html')
if __name__ == '__main__':
app.run(debug=True)

Getting 400 on Flask Unit Test

I'm writing a unit test for a file upload function in Flask.
The app works well locally but the unit test throws a 400. Thanks!
Here's my app.py
from flask import Flask, render_template, request
app = Flask(__name__)
app.config["TESTING"] = True
#app.route('/')
def index():
return render_template('index.html')
#app.route('/uploader', methods = ['GET','POST'] )
def upload_photo():
if request.method == 'POST':
photo = request.files['photo']
resp = app.make_response(photo.read())
resp.mimetype = 'image/jpeg'
return resp
if __name__ == '__main__':
app.run(debug=True)
Here's my test:
import unittest
import io
from app import app
class TestCase(unittest.TestCase):
def setUp(self):
self.client = app.test_client()
def test_upload_photo(self):
result = self.client.post('/uploader',
content_type='multipart/form-data', follow_redirects=True,
data=dict(upload_var=(io.BytesIO(b'photo'), 'photo')))
print(result.data)
self.assertTrue(result.status_code == 200)
if __name__ == "__main__":
unittest.main()`
Change upload_var to photo in the data dictionary, as that's what your handler function is expecting the file to be called.

Categories

Resources