Flask: Set session variable from URL Param - python

I have a website that needs to be rebranded depending on the URL that a visitor comes in on. For the most part, the content is the same but the CSS is different. I'm brand new to flask and relatively new to session cookies, but I think the best way to do this is to create a session cookie containing a "client" session variable. Then, depending on the client (brand), I can append a specific css wrapper to a template.
How can I access URL params and set one of the param values to a session variable? For example, if a visitor comes in on www.example.com/index?client=brand1, then I'd like to set session['client'] = brand1.
My app.py file:
import os
import json
from flask import Flask, session, request, render_template
app = Flask(__name__)
# Generate a secret random key for the session
app.secret_key = os.urandom(24)
#app.route('/')
def index():
session['client'] =
return render_template('index.html')
#app.route('/edc')
def edc():
return render_template('pages/edc.html')
#app.route('/success')
def success():
return render_template('success.html')
#app.route('/contact')
def contact():
return render_template('pages/contact.html')
#app.route('/privacy')
def privacy():
return render_template('pages/privacy.html')
#app.route('/license')
def license():
return render_template('pages/license.html')
#app.route('/install')
def install():
return render_template('pages/install.html')
#app.route('/uninstall')
def uninstall():
return render_template('pages/uninstall.html')
if __name__ == '__main__':
app.run(debug=True)

You could do so in a #flask.before_request decorated function:
#app.before_request
def set_client_session():
if 'client' in request.args:
session['client'] = request.args['client']
set_client_session will be called on each incoming request.

Related

Flask Python - How to pass variable from one method to another

I have a flask app and I need to pass variables from one function to another. The requirement here is I need to pass the value of 'skill' from index() to get_image(), any idea on how this can be achieved?
#app.route('/', methods=['POST'])
def index():
data = json.loads(request.get_data())
skill = data['conversation']['skill']
#app.route("/get-image/<image_name>")
def get_image(image_name):
if skill == 'getpositions':
# some code
You can try use flask sessions for example:
from flask import Flask, session
...
#app.route('/', methods=['POST'])
def index():
data = json.loads(request.get_data())
skill = data['conversation']['skill']
session['skill'] = skill
#app.route("/get-image/<image_name>")
def get_image(image_name):
if session['skill'] == 'getpositions':
#some code
Check the documentation.

How to call funcions with basic authentication enabled in Python

I am using basic authentication with the decorator in a flask application.
The code looks like:
from flask import Flask, Response, request
from functools import wraps
app = Flask(__name__)
app.config.from_object('settings')
def valid_credentials(username, password):
return username == app.config['USER'] and password == app.config['PASS']
def authenticate(f):
#wraps(f)
def wrapper(*args, **kwargs):
auth = request.authorization
if not auth.username or not auth.password or not valid_credentials(auth.username, auth.password):
return Response('Login!', 401, {'WWW-Authenticate': 'Basic realm="Login!"'})
return f(*args, **kwargs)
return wrapper
#app.route('/')
def index():
return 'Hello, world!'
#app.route('/secure')
#authenticate
def secure():
return 'Secure!'
#app.route('/check')
#authenticate
def check():
secure()
return 'checked'
if __name__ == '__main__':
app.run(debug=True)
But I am not able to call the secure function from check function due to the authentication. Now is it possible to call the function in the current scenario?
The usual method is to keep helper methods separate from views. For example:
def _secure():
return 'Secure!'
#app.route('/secure')
#authenticate
def secure():
return _secure()
You can then reuse the helper method (_secure()) from other places. Since it doesn't have a route associated it is not possible for a visitor to run it without authentication.
It is also a good idea to keep these helper methods in a separate module (such as helpers.py or utils.py).

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)

How do I mimic Java Springs #PathVariable using Python Flask

from flask import Flask, jsonify, request
from flask_restful import Api, Resource
app = Flask(__name__)
api = Api(app)
user_dict = {}
class User(Resource):
def __init__(self):
user_id = 0
def get(self):
return jsonify(user_dict[id])
api.add_resource(User, "/user")
if __name__ == "__main__":
app.run(debug=True)
The idea is that when a GET request is made to /user/1, then the get method returns that key/value pair of the user_dict. How do I do path variables in Python? Please assume that the dictionary is not empty.
Flask uses <variable_name> or <converter:variable_name> placeholders in URL path registrations.
This is used in the examples shown in the Flask-Restful Quickstart documentation:
class TodoSimple(Resource):
def get(self, todo_id):
return {todo_id: todos[todo_id]}
def put(self, todo_id):
todos[todo_id] = request.form['data']
return {todo_id: todos[todo_id]}
api.add_resource(TodoSimple, '/<string:todo_id>')
Here <string:todo_id> is a path variable, passed to the TodoSimple.get() and TodoSimple.put() methods as an argument.
Flask-Restful otherwise assumes a general familiarity with Flask's patterns, I strongly recommend you read through at least the Flask Quickstart document, and I recommend you also work through the tutorial, if nothing else.
For your specific example, if user ids are always integers, use:
class User(Resource):
def get(self, user_id):
return jsonify(user_dict[user_id])
api.add_resource(User, "/user/<int:user_id>")

flask-restful having a get/<id> and post with json in the same class

The get method on user works if the # api.add_resource(User, '/user/')
line is uncommented, and the other api.add_resource is.
The inverse of that is true to make the post method work.
How can I get both of these paths to work?
from flask import Flask, request
from flask.ext.restful import reqparse, abort, Api, Resource
import os
# set the project root directory as the static folder, you can set others.
app = Flask(__name__)
api = Api(app)
class User(Resource):
def get(self, userid):
print type(userid)
if(userid == '1'):
return {'id':1, 'name':'foo'}
else:
abort(404, message="user not found")
def post(self):
# should just return the json that was posted to it
return request.get_json(force=True)
api.add_resource(User, '/user/')
# api.add_resource(User, '/user/<string:userid>')
if __name__ == "__main__":
app.run(debug=True)
Flask-Restful supports registering multiple URLs for a single resource. Simply provide both URLs when you register the User resource:
api.add_resource(User, '/user/', '/user/<userid>')

Categories

Resources