Flask request.args,get not working properly - python

I want to use request.args.get() and log my data out into the console. So, I want the console to log {username: "ani", room: "1"} but it is only printing out {username: "ani", room: ""}. Here is my app.py-
from flask import Flask, render_template, request, redirect, url_for
from flask_socketio import SocketIO, join_room
app = Flask(__name__)
socketio = SocketIO(app)
#app.route('/')
def home():
return render_template('index.html')
#app.route('/chat')
def chat():
username = request.args.get('username')
room = request.args.get('room')
if username and room:
return render_template('chat.html', username=username, room=room)
else:
redirect(url_for('home'))
#socketio.on('join_room')
def handle_join_room(data):
app.logger.info("{} has joined room {}".format(
data['username'], data['room']))
join_room(data['room'])
socketio.emit('join_room_announcement', data)
if __name__ == '__main__':
socketio.run(app, debug=True)
Here is my chat.html-
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Chat App</title>
</head>
<body>
<h1>Welcome to room {{ room }}</h1>
<div id="messages"></div>
<form>
<input type="text" placeholder="Enter your message here" />
<button type="submit">Send</button>
</form>
</body>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.1.1/socket.io.js"
integrity="sha512-oFOCo2/3DtjrJG4N27BjSLQWoiBv171sK6a+JiWjp/7agxC2nCUP358AqzxkBUb5jX8g6CYLPdSKQTbC0weCwA=="
crossorigin="anonymous"
></script>
<script>
const socket = io.connect('http://127.0.0.1:5000/');
socket.on('connect', () => {
socket.emit('join_room', {
username: '{{ username }}',
room: '{{ id }}',
});
});
socket.on('join_room_announcement', (data) => {
console.log(data);
});
</script>
</html>
It also does this in the terminal saying ani has joined room when it should say the room id.
Welcome to {{ Room {{ room }} still works in chat.html as it shows me the room id there. Please help. If you need any more information, you can comment.

In your script block in HTML you are trying to access room via variable name id as below
room: '{{ id }}',
But in flask you are setting the value to room. So use below
room: '{{ room }}',
Above change will address both console.log issue and terminal logging issue.

Related

Flask cannot redirect after receiving post request from Ajax in templates

I want to create a chatroom, in which, if people enter "!exit", then they will get out of the chatroom. The way I implement this idea is that whenever people send "!exit" message, Ajax will send a post request back to the view function. After receiving the request, the view function redirects the user to the homepage. However, right now, I think I can send a post request, since the console prints "success", but the code still does not redirect. This is my code:
In chat.html:
<head>
<title> Chat room </title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.8/socket.io.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function() {
var socket = io.connect('http://127.0.0.1:5000');
socket.on('message', function(msg) {
if (msg=="!exit") {
$.ajax({
type : "POST",
url : "http://127.0.0.1:5000/chat",
data: {data: "Unmatched"},
contentType: 'application/json;charset=UTF-8',
success: function() {
window.location.href = '/chat'
}
});
}
else {
$("#message-display").append('<div>'+ "person: " + msg+'</div>');
}
});
$('#sendbutt').on('click', function() {
socket.send($('#message-input').val());
$('#message-input').val('');
});
});
</script>
<div> Welcome to the chat room. You are chatting with a user. </div>
<div> Type "!exit" if you want to stop chatting and return to the homepage. </div>
<l id="message-display"> </l>
<input type="text" id="message-input">
<button id="sendbutt"> Send </button>
</body>
</html>
In main.py:
socketio=SocketIO(app)
#app.route('/', methods = ["GET", "POST"])
def homepage():
return render_template('home.html')
#app.route('/chat', methods = ["GET", "POST"])
def chat():
if request.method == "POST":
return redirect(url_for('homepage'))
return render_template("chat.html")
#socketio.on('message')
def handle_message(msg):
send(msg,broadcast=True)

Send variables from Python Flask to HTML

I have following Problem:
i want to send some data to Html from Python with button Click in HTML, but wenn i click the button it doesn't work at all.
Here is my code:
*
python.py:
from flask import Flask, render_template, flash, Markup, request
app = Flask(__name__)
#app.route('/')
def index():
return render_template('new.html')
#app.route('/SomeFunction', methods = ['POST', 'GET'])
def SomeFunction():
if request.method == 'GET':
text = 'Name'
print("result:")
return render_template("new.html",text = text)
if __name__ == '__main__':
app.run()
and here is my Html:
<!doctype html>
<html>
<head>
<title>The jQuery Example</title>
<div class="flashes">
{% for message in get_flashed_messages()%}
{{ message }}
{% endfor %}
</div>
<h2>jQuery-AJAX in FLASK. Execute function on button click</h2>
<script type="text/javascript" {{ url_for('static', filename='app.js')}}></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"> </script>
<script type=text/javascript> $(function() { $("#mybutton").click(function (event) { $.getJSON('/SomeFunction', { }, function(data) { }); return false; }); }); </script>
</head>
<body>
<input type = "button" id = "mybutton" value = "Click Here" />
<p>text: {{text}}</p>
</body>
</html>
So what i want is when i press the input button it will show the name what is in python defined. Maybe there are other ways what can make it works, but i need exactly in python.
Okay so passing variables from python flask to html is easy.
Import json
make a dictionary object with key whatever you want and assign your variable to that key
jobj = { 'name' : name }
Now dump this object as json and pass as argument
return render_template('htmlfile.html', res=json.dumps(jobj))
Now you would be able to access the res json in JavaScript in htmlfile.html
<Script>
var res = JSON.parse(' {{ res | safe }} ');
console.log(res.name);
</Script>

How to create a web push notification using Flask

I'm trying to implement a web push notification in my project. Using some tutorials I got create an alert on index page when I post a message. But it's far from being what I want.
index.html
<html>
<head>
<title>Test Page</title>
</head>
<body>
<h1>Testing...</h1>
</body>
<script
src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<script type="text/javascript">
var source = new EventSource('/stream');
source.onmessage = function (event) {
alert(event.data);
};
</script>
</html>
post.html
<html>
<head>
<title>Posting a Message</title>
</head>
<body>
<form action="{{url_for('post')}}" method='post'>
Message: <input type="text" name="message" size='50'> <input type="submit" value="Launch!">
</form>
</body>
</html>
app.py
#!/usr/bin/env python
from flask import Flask, render_template, request, session, Response
from redis import Redis
import datetime
app = Flask(__name__)
app.secret_key = 'asdf'
red = Redis(host='localhost', port=6379, db=0)
def event_stream():
pubsub = red.pubsub()
pubsub.subscribe('notification')
for message in pubsub.listen():
print message
yield 'data: %s\n\n' % message['data']
#app.route('/post', methods=['POST','GET'])
def post():
if request.method=="POST":
message = request.form['message']
now = datetime.datetime.now().replace(microsecond=0).time()
red.publish('notification', u'[%s] %s: %s' % (now.isoformat(), 'Aviso', message))
return render_template('post.html')
#app.route('/stream')
def stream():
return Response(event_stream(),
mimetype="text/event-stream")
#app.route('/')
def index():
return render_template('index.html')
if __name__=="__main__":
app.run(host='0.0.0.0', port=8001, debug=True,threaded=True)
Well, I would like to implement a subscribe system, I think that is how is called. The user allow to receive notification from the website and when he clicks on the "news" it opens a new page with the detailed content.
The index page does not need to be opened for receving the message.

simple flask app server passing data with ajax and jquery

I've spent all day tinkering with this app trying to get some simple information passed to the back end of the application. I am using a simple flask app and trying to send data from a search query to the back end using ajax. However, I have been completely unsuccessful. Any help would be greatly appreciated.
Below is app.py
from scraper import scrape
from flask import Flask, render_template, jsonify, make_response, request
import json
app = Flask(__name__)
#app.route("/")
def index():
entries = json.dumps(scrape("video games"))
return render_template('index.html', entries= entries)
#app.route('/parse_data', methods=['GET', 'POST'])
def parse_data():
if request.method == "GET":
#data = request.form("blah")
#print("blah")
search = request.json
#new_search = json.dumps(scrape(data))
return search
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=5000)
and index.html
<!DOCTYPE html>
<html>
<head>
<title>Flask app</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
</head>
<body>
<div class="topnav">
<a class="active" href="#home">Home</a>
About
Contact
<form name = "textbox" id = "textbox">
<input id ="textbox" name="textbox" type="text" placeholder="Search..">
<button type="submit">submit</button>
</form>
</div>
<p>you searched: {{search}} </p>
<div id="div1">
<p id="p1"></p>
<p id="p2"></p>
</div>
<script>
var value = $('.textbox').val();
//alert(value);
$.ajax({
type: 'POST',
url: "/parse_data",
data: JSON.stringify(value)
contentType: 'application/json',
success: function(data){
alert("success")
}
});
var jsonz = {{ entries|tojson }};
var s = JSON.parse(jsonz);
var i;
for (i = 0; i < s.length; i++) {
var para = document.createElement("p");
var node = document.createTextNode(s[i].product_name + "\n" + s[i].product_link);
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
}
//document.getElementById("user").innerHTML =
//obj;
//"Name: " + obj.product_name + "<br>" +
//"Location: " + obj.product_link;
</script>
</body>
</html>
Your code snippet has a few issues, mostly:
Your AJAX request is not bind to the button click event, so clicking the button does nothing.
You have two html elements with the same id textbox, id are supposed to be unique.
To get an html element by id use "#textbox"
On the server side (Flask):
Use the function get_json() of the request
To process the POST request you need to check for POST not GET
Try wrapping your POST request like this:
$("button").click(function (e) {
e.preventDefault();
var value = $("#textbox").val();
alert(value);
$.ajax({
type: "POST",
url: "parse_data",
data: JSON.stringify({ "text" : value } ),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
alert(JSON.stringify(data));
}
});
});
Also remove the duplicate ids textbox, change the id of the form to something like textbox-form, finally change your parse_data function to something like this:
#app.route('/parse_data', methods=['GET', 'POST'])
def parse_data():
if request.method == 'POST':
search = request.get_json()
return jsonify(search)
return render_template('index.html')

Flask - Toggle button with dynamic label

I am new to Flask and want to create a On/Off toggle button on my website. I was wondering if and how this is possible also including a dynamic label. The following picture shows what I have in mind:
I was thinking about using a wtfforms SubmitField but I don't quite know how to implement this dynamic behavior between my routes.py file and my html template. I was thinking something like this:
forms.py:
from flask_wtf import FlaskForm
from wtforms import SubmitField
class PowerSwitchForm(FlaskForm):
power_switch = SubmitField("ON")
routes.py:
from flask import render_template, flash, redirect, url_for
from app import app
from app.forms import PowerSwitchForm
#app.route('/power', methods=['GET', 'POST'])
def power():
power_switch = PowerSwitchForm()
if power_switch.power_switch.label.text == "ON" and power_switch.validate():
flash("Power has been turned ON")
power_switch.power_switch.label.text = "OFF"
return redirect(url_for('power')
elif power_switch.power_switch.label.text == "OFF" and power_switch.validate():
flash("Power has been turned OFF")
power_switch.power_switch.label.text = "ON"
return redirect(url_for('power')
return render_template('power.html', form0=power_switch)
power.html:
<!DOCTYPE html>
{% extends "base.html" %}
{% block content %}
<h2>Power switch</h2>
<form action="" method="post" novalidate>
{{ form0.hidden_tag() }}
{{ form0.power_switch() }}
</form>
{% endblock %}
You can use jquery to handle the desired operation when the toggle button is clicked. Also, if there is a backend process that should be performed when the button is toggled, ajax can be used. This answer demonstrates both. bootstrap-toggle is a library that enables simple implementation of a toggle. To use, copy the header tag values below:
Simple toggle that displays "toggled" or "untoggled":
<html>
<body>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"></script>
<link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet">
<script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script>
</head>
<input type="checkbox" class='toggle' checked data-toggle="toggle">
<div class='status'>Toggled</div>
</body>
<script>
$(document).ready(function() {
$('.toggle').click(function() {
var current_status = $('.status').text();
if (current_status === 'Untoggled'){
$('.status').html('Toggled');
}
else{
$('.status').html('Untoggled');
}
});
});
</script>
</html>
Toggle that triggers backend script for both "toggled" or "untoggled":
In the template, slightly change the script:
<script>
$(document).ready(function() {
$('.toggle').click(function() {
var current_status = $('.status').text();
$.ajax({
url: "/get_toggled_status",
type: "get",
data: {status: current_status},
success: function(response) {
$(".status").html(response);
},
error: function(xhr) {
//Do Something to handle error
}
});
});
});
</script>
Then, in your app, create a route /get_toggled_status:
#app.route('/get_toggled_status')
def toggled_status():
current_status = flask.request.args.get('status')
return 'Toggled' if current_status == 'Untoggled' else 'Untoggled'
This example does the same thing as the pure html/jquery solution, however, it does demonstrate how the backend can be communicated with when using the toggle.
I am also new to Flask. And here is the pure python code with flask that I've tried.
Looks it work.
in templates/demo.html :
{% extends "bootstrap/base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block content %}
<div class="page-header">
{{ wtf.quick_form(form) }}
</div>
{% endblock %}
in demo.py :
from flask import Flask, render_template, redirect, url_for
from flask_bootstrap import Bootstrap
from flask_wtf import FlaskForm
from wtforms import SubmitField
class PowerState(FlaskForm) :
state = SubmitField('OFF')
app = Flask(__name__)
Bootstrap(app)
app.config['SECRET_KEY'] = 'YOUR SECRET KEY'
#app.route('/', methods=['GET', 'POST'])
def home() :
form = PowerState()
if form.validate_on_submit() :
if form.state.label.text == 'OFF' :
PowerState.state = SubmitField('ON')
elif form.state.label.text == 'ON' :
PowerState.state = SubmitField('OFF')
return redirect(url_for('home'))
return render_template('demo.html', form=form)
then run :
flask run
Regards, Alex.Wu

Categories