Flask render template in socket.io callaback - python

I'm using the Flask-socketio library for a python project and it seems it's not possible to use render_template in a socket.io callback. I could of course send the redirection url with emit and redirect my page in javascript like here but the problem is that I have to pass a variable in the render template. So I have a button on my index page that redirects to the process page and sends the process message with socket.io.
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
app = Flask(__name__)
socketio = SocketIO(app)
#app.route("/")
def index():
return render_template('index.html')
#app.route("/process")
def format():
return render_template('process.html')
#socketio.on('process')
def do_process():
if process() == 0:
return render_template('index.html')
else:
return render_template('index.html', description=MSG_ERROR)
if __name__ == "__main__":
socketio.run(app)

Related

Flask in showing 404 Error in Existing Routes

I am facing a very weird Issue, In my Flask App when index route (https://sitename.com/) is called everything is fine, but as i navigate to a route like https://sitename.com/about it shows 404 Error, even when About route is created in main.py . This App works all perfect in localhost:5000 but when I deployed it too a VPS It is showing that Error of showing 404 on every route
My main.py
from os import environ
from flask import Flask, redirect, render_template, request, url_for
import requests
import json
import datetime
def getUserData(route):
if request.headers.getlist("X-Forwarded-For"):
ip = request.headers.getlist("X-Forwarded-For")[0]
else:
ip = request.remote_addr
with open("users.txt", "a") as f:
f.write(f"Page Visited: {route}\n")
f.write(f"User Agent: {request.headers.get('User-Agent')}\n")
f.write(f"Remote Addr: {ip}\n")
f.write(f"DateTime: {datetime.datetime.now()}\n")
f.write(f"\n\n\n")
app = Flask(__name__)
app.debug = True
# Website
#app.route('/')
def index():
getUserData("Index Page")
return render_template('index.html')
#app.route('/gallery')
def gallery():
getUserData("Gallery")
return render_template('pages/gallery.html')
#app.route('/faqs')
def faqs():
getUserData("FAQs")
return render_template('pages/faqs.html')
#app.route('/about')
def about():
getUserData("About")
return render_template('pages/about.html')
#app.route('/contact')
def contact():
getUserData("Contact")
return render_template('pages/contact.html')
# 404 Handling
#app.errorhandler(404)
def not_found(e):
getUserData("404 Page")
return render_template("pages/404.html")
if __name__ == '__main__':
app.run()

Supress Redirecting by triggering a form action using Flask [duplicate]

This question already has an answer here:
Redirect back in Flask
(1 answer)
Closed 2 years ago.
I would like to use flask to define the action for a button. However, after triggering the action, I will automatically be redirected. E.g. having a button definition using the following html:
<html>
<body>
<form action="/do_something" method="post">
<button>Do something!</button>
</form>
</body>
</html>
And the action handling by the given python script:
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/")
def root():
return render_template("test_3.html")
#app.route("/do_something", methods=["POST"])
def something():
return 'Something'
app.run()
In this case, I start with the url "/". By clicking on the button "Do Something", I will automatically be redirected to the url "/do_something". What I actual want is:
Perform Action
Refresh the original page
Can some one help?
If the POST request to /do_something can occur on any page, I would recommend redirecting back to the request's referrer, which will "refresh" the page.
E.g
from flask import Flask, render_template, request, redirect
app = Flask(__name__)
#app.route("/")
def root():
return render_template("test_3.html")
#app.route("/do_something", methods=["POST"])
def something():
# Do things
return redirect(request.referrer or request.host_url)
app.run()
Otherwise you can specify the page to go to with redirect() and url_for()
Example:
from flask import Flask, redirect, render_template, url_for
app = Flask(__name__)
#app.route("/")
def root():
return render_template("test_3.html")
#app.route("/do_something", methods=["POST"])
def something():
# Do things
return redirect(url_for("app.root"))
app.run()

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)

Serving static json data to flask

I have json data in demo_data.json that I'd like to bring into a Flask app. I'm receiving a 404 on the file which I've placed in the static directory, my code is below, thanks for any thoughts in advance:
from flask import Flask, render_template
from flask import url_for
app = Flask(__name__, static_url_path='/static/')
#app.route('/')
def home():
return render_template('home.html')
#app.route('/welcome')
def welcome():
return render_template('welcome.html')
if __name__ == '__main__':
app.run()
return send_from_directory('/static', 'demo_data.json')
You would need to define the view to send the data.
Something similar to :
from flask import Flask, render_template
from flask import url_for
app = Flask(__name__, static_url_path='/static/')
#app.route('/')
def home():
return render_template('home.html')
#app.route('/welcome')
def welcome():
return render_template('welcome.html')
#app.route('data/<filename>')
def get_json(filename):
return send_from_dir
if __name__ == '__main__':
app.run()
So, you are trying to send a file? Or show a file in an url?
I assumed the later. Notice the use of url_for.
This creates a link that will show your static file.
http://127.0.0.1:5000/send and http://127.0.0.1:5000/static/demo_data.json
from flask import Flask, render_template
from flask import url_for
app = Flask(__name__, static_url_path='/static')
#app.route('/')
def home():
return render_template('home.html')
#app.route('/send')
def send():
return "<a href=%s>file</a>" % url_for('static', filename='demo_data.json')
if __name__ == '__main__':
app.run()
But you also might want to check out https://github.com/cranmer/flask-d3-hello-world
It looks like you have a trailing slash on your static_url_path. Removing the extra character resolved the issue. Also note the removed last line. The return call wasn't necessary and the function call after the return was a syntax error.
from flask import Flask, render_template
from flask import url_for
app = Flask(__name__, static_url_path='/static')
#app.route('/')
def home():
return render_template('home.html')
#app.route('/welcome')
def welcome():
return render_template('welcome.html')
if __name__ == '__main__':
app.run()

Flask, Blueprint, current_app

I am trying to add a function in the Jinja environment from a blueprint (a function that I will use into a template).
Main.py
app = Flask(__name__)
app.register_blueprint(heysyni)
MyBluePrint.py
heysyni = Blueprint('heysyni', __name__)
#heysyni.route('/heysyni'):
return render_template('heysyni.html', heysini=res_heysini)
Now in MyBluePrint.py, I would like to add something like :
def role_function():
return 'admin'
app.jinja_env.globals.update(role_function=role_function)
I will then be able to use this function in my template. I cannot figure out how I can access the application since
app = current_app._get_current_object()
returns the error:
working outside of request context
How can I implement such a pattern ?
The message error was actually pretty clear :
working outside of request context
In my blueprint, I was trying to get my application outside the 'request' function :
heysyni = Blueprint('heysyni', __name__)
app = current_app._get_current_object()
print(app)
#heysyni.route('/heysyni/')
def aheysyni():
return 'hello'
I simply had to move the current_app statement into the function. Finally it works that way :
Main.py
from flask import Flask
from Ablueprint import heysyni
app = Flask(__name__)
app.register_blueprint(heysyni)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(debug=True)
Ablueprint.py
from flask import Blueprint, current_app
heysyni = Blueprint('heysyni', __name__)
#heysyni.route('/heysyni/')
def aheysyni():
# Got my app here
app = current_app._get_current_object()
return 'hello'

Categories

Resources