Flask Session Cookie Expiration - python

I am trying to set the expiration for a cookie to be longer than the browser session. My config.py is:
from datetime import timedelta
SESSION_FILE_DIR = 'C:/some/path15'
SECRET_KEY= 'abcdefg'
DEBUG = True
SESSION_PERMANENT = True
PERMANENT_SESSION_LIFETIME = timedelta(days=30)
And then to mimic my app structure for this example, I have the main app which registers a blueprint:
from flask import Flask, render_template, request, session, current_app
from flask_session import Session
import tempfile
server = Flask(__name__)
server.config.from_pyfile('config.py')
### Import and Register Blueprints
from tools.routes import my_bp
server.register_blueprint(my_bp)
#server.route('/')
def homepage():
return "Hello"
if __name__ == '__main__':
server.run(debug=True)
And then a blueprint called routes.py living in a subdirectory of the main app called tools
from flask import Flask, render_template, request, session, Blueprint, current_app
from flask_session import Session
import tempfile
my_bp = Blueprint("my_bp", __name__)
#my_bp.route('/new', methods=['POST', 'GET'])
def path():
if 'path' not in session: ##new
session['path'] = tempfile.mkdtemp() ##new
path = session['path'] ##new
return path
When running this app (head over the /new route), if I Inspect Element under Storage in the browser, it shows that the cookies expire/max_age is Session.
How can I get this to respect the 30-day expiration I have set in the config.py file?

from flask import session, app
#app.before_request
def before_request():
session.permanent = True
app.permanent_session_lifetime = datetime.timedelta(minutes=20) # session will be alive for 20 minutes

Related

Running into NameError: name 'app' is not defined when trying to upload image into file [duplicate]

This question already has answers here:
Flask: How to use app context inside blueprints?
(2 answers)
Closed 8 months ago.
My problem occurs mainly when I try and upload a picture in a separate html form. Before I added the app.config I would successfully get POST and GET requests. On visual code it tells me that app is not defined but I'm not sure how to define it in my image.py file.
This is my image.py file app.config
from unicodedata import category
from flask import Flask, Blueprint, render_template, request, flash, jsonify, url_for, redirect
import urllib.request
from werkzeug.utils import secure_filename
from flask_login import login_required , current_user
from .models import Note
from .import db
import json
import os
image = Blueprint('image', __name__)
#image.route('/', methods=['GET','POST'])
#login_required
def Upload():
if request.method == "POST":
if request.files:
image = request.files["image"]
image.save(os.path.join(app.config['IMAGE_UPLOADS'], image.filename))
print("image saved")
return redirect(request.url)
return render_template("image.html", user=current_user)
My init.py file with my app configurations.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from os import path
from flask_login import LoginManager
db = SQLAlchemy()
DB_NAME = "database.db"
def create_app():
app = Flask(__name__)
#Secret key into app
app.config['SECRET_KEY'] = '****'
app.config['IMAGE_UPLOADS'] = r"C:\Users\qw\Desktop\StCh\website\static\Images"
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
and finally my main.py file to run the app.
from website import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
the error keeps on occurring even after I try and import from website or
I resolved it by just adding
app = Flask(__name__)
into my image.py file. Feel stupid

Flask Session loses login session data on refresh

I'm currently building a Chat App using Flask and Flask Socketio. In order to save the client's current chat-room, I use the flask_session module with the session type "filesystem". I also use Flask-Login module so the client is logged in with an account. So when I log the client in, the session contains the client's login data from the Flask-Login module. But as soon as I refresh the chat page, the Flask_login data is gone and the current user variable from the Flask-Login module becomes an AnonymousMixin object which causes my program to crash. So what causes the FileSystemSession to lose the current_user data after refreshing the page?
This is the output when I print the session and the current_user before and after the refresh of the page:
Before:
<FileSystemSession {'_permanent': True, 'csrf_token': 'f687c55dbf48c0b9cd1e4601729ba687f74e255b', 'current_room': 'Lobby', '_fresh': True, '_user_id': '1', '_id': '4825ca5a26d88cfc91bcb75ef854505f0d4cdc736affaac2fd3211fb6015b34490c6ec47ec7175dee531442ec8d3a1d5f092c4de1349ca0d48fe723aed678c5a', '_flashes': [('success', 'Logged in successfully')]}>
<User 1>
After:
<FileSystemSession {'_permanent': True, 'csrf_token': 'f687c55dbf48c0b9cd1e4601729ba687f74e255b', 'current_room': 'Lobby'}>
<flask_login.mixins.AnonymousUserMixin object at 0x000002CD3CFB6910>
Here's my code:
__init__.py
from flask import Flask
from flask_session import Session
from flask_login import LoginManager
from .models import *
from os import path
app = Flask(__name__)
def create_app():
app.config["SECRET_KEY"] = "secret!"
app.config["SESSION_TYPE"] = "filesystem"
app.config["SQLALCHEMY_DATABASE_URI"] = f"sqlite:///{DB_NAME}"
login_manager = LoginManager()
login_manager.init_app(app)
Session(app)
#login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
db.init_app(app)
from .application import socketio
from .views import views
from .auth import auth
app.register_blueprint(views, url_prefix="/")
app.register_blueprint(auth, url_prefix="/")
return socketio, app
views.py
from flask import Blueprint, render_template, flash, redirect, url_for, request, session
from flask_login import current_user, login_required
views = Blueprint("views", __name__)
#views.route("/", methods=["GET", "POST"])
def index():
return render_template("index.html", user=current_user)
#views.route("/chat", methods=["GET", "POST"])
def chat():
return render_template("chat.html", user=current_user, rooms=current_user.rooms, current_room=Room.query.filter_by(room_name=session["current_room"]).first())
I don't know if this is important but I also put in the flask_socketio part, which changes the session when the room is changed:
from flask import session
from flask_socketio import SocketIO, emit, send, join_room, leave_room
from app import app
socketio = SocketIO(app, manage_session=False)
#socketio.on('join')
def on_join(data):
user = data["username"]
room = data["room"]
join_room(room)
session["current_room"] = room
emit("room-manager", {"message": f"{user} has joined the {room} room"}, room=room)

how to implement Flask-Dance with Flask Blueprints

I tried to use Flask-Dance with normal flask app and it works and if I try to implement with flask blueprints it doesn't work. How to register flask-dance to flask blueprints?
My views.py for auth blueprint
from flask import render_template, url_for, redirect, current_app, request
from app.auth import auth
from flask_dance.contrib import github
#auth.route('/login')
def login():
return render_template('auth/login.html')
#auth.route("/")
def github():
if not github.authorized:
return redirect(url_for("github.login"))
resp = github.get("/user")
assert resp.ok
return "You are #{login} on GitHub".format(login=resp.json()["login"])
my init.py for auth blueprint
from flask import Blueprint
from flask_dance.contrib.github import make_github_blueprint, github
auth = Blueprint('auth', __name__, url_prefix='/auth')
blueprint = make_github_blueprint(client_id="m-client-id",client_secret="my-client-secret")
auth.register_blueprint(blueprint, url_prefix="/auth")
from app.auth import views
and my main init.py file:
from flask import Flask
from flask_fontawesome import FontAwesome
from app.config import Config
fa = FontAwesome()
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(Config)
fa.init_app(app)
from app.public import public
app.register_blueprint(public)
from app.auth import auth
app.register_blueprint(auth)
return app
First you should create and register different blueprint for github.
github/init.py
from flask_dance.contrib import github
from flask_dance.contrib.github import make_github_blueprint
github_blueprint = make_github_blueprint(client_id='your-client-id',client_secret='your-client-secret')
from app.github import views
github/views.py
#github_blueprint.route("/")
def github_login():
if not github.authorized:
return redirect(url_for('github.login'))
account_info = github.get('/user')
if account_info.ok:
account = account_info.json()
return '<h1>Your Github name is {}'.format(account['login'])
and finally in your main init.py file
from flask import Flask
from flask_fontawesome import FontAwesome
from app.config import Config
fa = FontAwesome()
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(Config)
fa.init_app(app)
from app.public import public
app.register_blueprint(public)
from app.auth import auth
app.register_blueprint(auth)
from app.github import github_blueprint
app.register_blueprint(github_blueprint, url_prefix='/github_login')
#/github_login=callback url
return app

Flask x Apscheduler - RuntimeError: RuntimeError: Working outside of application context

I am getting the following error when trying to set up a scheduled job for my flask app:
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.
I have tried to include the function 'print_session' (which is just a dummy function to check the session data will pull through - in reality this function will query a database) with a 'current_app.appcontext() with loop as I have seen on a few other apps but no joy. Does anyone know why it is still out of the application context?
main.py
from website import create_app
app = create_app()
if __name__=="__main__":
app.run(debug=True,host='localhost',port=5000,threaded=True)
init.py
from flask import Flask, session
from flask_sqlalchemy import SQLAlchemy
from os import path
from flask_session import Session
from flask_login import LoginManager
import redis
db = SQLAlchemy()
DB_NAME = 'sqlite:///db.sqlite3'
sess=Session()
login_manager = LoginManager()
def create_app():
app = Flask(__name__)
app.config['SECRET_KEY'] = "SECRET_KEY"
app.config['SQLALCHEMY_DATABASE_URI'] = SQLALCHEMY_DATABASE_URI
app.config['SESSION_TYPE'] = 'SESSION_TYPE'
app.config['SESSION_REDIS'] = 'SESSION_REDIS'
db.init_app(app)
sess.init_app(app)
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
# with app.app_context():
from .views import views
from .auth import auth
app.register_blueprint(views,url_prefix='/')
app.register_blueprint(auth,url_prefix='/')
from .models import User,Token
create_database(app)
return app
def create_database(app):
db.create_all(app=app)
print('Created database')
views.py
from flask import Blueprint,render_template,session,redirect,request,url_for
from flask import current_app
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.schedulers.blocking import BlockingScheduler
import datetime
from flask_login import login_required,current_user
from requests_oauthlib import OAuth2Session
from . import db
from .models import Token
from functools import wraps
def print_session(value):
with current_app.app_context():
print('Yes',value)
return(redirect(url_for('views.home')))
#views.route('/start_schedule')
#login_required
def start_xero_schedule():
with app.app_context():
sched = BackgroundScheduler()
sched.add_job(print_session,'interval',args=[session['value']],seconds=10)
sched.start()
return(redirect(url_for('views.xero')))

Flask Configuration for Sharing Resources Across Blueprints

I have an extremely large application that is factored into many blueprints. I need to configure the entire application to save files into a directory when a user uploads files. So I am setting ["SESSION_FILE_DIR"] = 'C:/some/path' to the path where files would live after upload in the app.py file.
The documentation reads that configuration settings are shared across the blueprints. I'm experiencing one issue that is not working and below is a stripped down example to replicate my problem to support my question. So, to debug I've created an extremely simple version just printing the path to screen to see what is happening.
If I head over to the URL .../print_dir then the ["SESSION_FILE_DIR"] = 'C:/some/path' is printed to screen. However, if I head over to the URL defined within the blueprint .../new then I am given an error of NameError: name 'server' is not defined.
How can I configure my app such that the same ["SESSION_FILE_DIR"] can be used across blueprints?
The contents of my main app.py are as follows:
from flask import Flask, render_template, request, session
from flask_session import Session
import tempfile
server = Flask(__name__)
server.config["SESSION_PERMANENT"] = False
server.config["SESSION_TYPE"] = "filesystem"
server.config["SESSION_FILE_DIR"] = 'C:/some/path'
server.secret_key = 'abcdefg'
### Import and Register Blueprints
from tools.routes import my_bp
server.register_blueprint(my_bp)
#server.route('/')
def homepage():
return "Hello"
#server.route('/print_dir')
def homepage2():
return server.config["SESSION_FILE_DIR"]
if __name__ == '__main__':
server.run(debug=True)
and now suppose the blueprint lives in a subdirectory called tools and contains the following:
from flask import Flask, render_template, request, session, Blueprint
from flask_session import Session
my_bp = Blueprint("my_bp", __name__)
#my_bp.route('/new', methods=['POST', 'GET'])
def path():
path = server.config["SESSION_FILE_DIR"]
return path
To access the app.config from within a Blueprint, you can import current_app from flask.
Example:
# ./app.py
from flask import Flask
from views.blueprint import bp
app = Flask(__name__)
# Set the config you want:
app.config['IMPORTANT_DIRECTORY'] = '~/path/to/important/directory'
# Register your blueprint
app.register_blueprint(bp)
# ./views/blueprint.py
from flask import Blueprint, current_app
bp = Blueprint('bp', __name__)
#bp.route('/path')
def get_path():
# access the config
path = current_app.config['IMPORTANT_DIRECTORY']
return path
You can find more info in the api docs for flask.

Categories