I have this very basic chat app, where everyone can chat in one huge group. And when I send messages, other people have to refresh their web page to see new messages. I am just wondering if anyone has any idea how to do this. By the way, the app is made with python Flask and HTML.
from flask import Flask, render_template, request, url_for, redirect
import database as db
app = Flask(__name__)
app.secret_key = 'ItDoesntMatter'
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'GET':
return render_template('/index.html', messages=db.get_messages())
#Else
message = request.form['message']
db.send_message(message)
return redirect(url_for('index'))
if __name__ == '__main__':
app.run()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chat</title>
</head>
<body>
{% for message in messages %}
<div>At {{ message[1] }}: <strong>{{ message[0] }}</strong></div>
{% endfor %}
<form method="POST" action="/">
<input type="text" placeholder="message" name="message">
<button type="submit" id="btn">Send</button>
</form>
</body>
</html>
I tried to do this with a turbo-flask, but it didn't work. I was also on google for like 1 hour and I didn't find anything.
Related
I have been working on a web interface using Flask and having some issues with back button in browser as after logging out hitting it takes user back inside. I have found similar questions and tried their answers but the issue is not resolved. I am attaching a simple example kindly have a look at it.
Main
from flask import Flask, request,session, redirect, url_for, render_template
from os import urandom
app = Flask(__name__)
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
app.secret_key = urandom(24)
#app.route('/', methods=['POST', 'GET'])
def index():
if request.method == 'POST':
session['Email id'] = request.form.get('Email Id')
Pass = request.form.get('Password')
try:
if session['Email id'] == 'KK#gmail.com' and Pass == 'KKK':
return render_template('Logged_in.html')
except:
return render_template('login.html')
return render_template('login.html')
#app.route('/sign_out')
def sign_out():
session.pop('Email id')
return redirect(url_for('index'))
#app.after_request
def add_header(r):
r.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
r.headers["Pragma"] = "no-cache"
r.headers["Expires"] = "0"
r.headers['Cache-Control'] = 'public, max-age=0'
return r
if __name__ == '__main__':
app.run(host="0.0.0.0", debug=True, threaded=True)
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="{{ url_for('index') }}" method="POST" id="login" class="input-group">
<input type="text" class="input-field" placeholder="Email Id" required name="Email Id">
<input type="text" class="input-field" placeholder="Password" required name="Password">
<button type="submit" class="submit-btn" style="color: white;">Log in</button>
</form>
</body>
</html>
Logged_in.html
<h2>You are Logged in</h2>
<i class="fas fa-sign-out-alt"></i>Log out
Your problem is that when users push the back button their browser will re-do the POST request. You need to use the POST/redirect/GET pattern to prevent this. For this you need four endpoints in totalt:
GET / : Check in the session that the user is logged in and render Logged_in.html, otherwise redirect to /login.html
GET /login.html : Render login.html
POST /sign_in : Check username and password. If successful, update the session and redirect to /
POST /sign_out : Log out the user session and redirect to /login.html
Do not render templates in your POST endpoints, just make them manipulate the session and then redirect.
I am trying to write a program that reads a file and outputs it to the textarea. The user can then edit the file and then click the submit button in order to submit the changes.
Currently, I have a method of obtaining the user's input (request.form), however I do not know how to prepopulate the text area element.
Flask
from flask import Flask
from flask import render_template
from flask import request
app = Flask(__name__)
#app.route('/')
def hello():
return render_template("index.html")
#app.route('/', methods=['POST'])
def submit():
return 'You entered: {}'.format(request.form['whitelist'])
if __name__ == '__main__':
app.run(host="localhost", port=8000, debug=True)
HTML
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Index</title>
</head>
<body>
<h1 style="color: blue">Index</h1>
<p>This is an HTML file served up by Flask</p>
<p>Whitelist:</p>
<form action="{{ url_for('submit') }}" method="post">
<textarea id="whitelist" name="whitelist" rows="4" cols="50"></textarea>
<input type="submit">
</form>
</body>
</html>
So is their a method that exists such that one can prepopulate the textarea?
Example
my_file_data = read_my_file(file)
Flask.output(element_id = "whitelist", input = my_file_data)
Implementing Solution
Try the following changes in your code (i assume that your file is a .txt but it can work with other file types with some changes):
Flask
#app.route('/')
def hello():
with open('your_file') as f:
t=f.read()
return render_template("index.html", t=t)
HTML
<textarea id="whitelist" name="whitelist" rows="4" cols="50"> {{t}} </textarea>
I am trying to create a site with a webform using Flask, but I keep getting a 500 error
Here is my template/main.html
<DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Sample Page</title>
<meta name="viewport" content="width=device-width"
initial=scale=1/>
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='favicon.ico') }}" rel="shortcut icon">
</head>
<h2>Hello, this site is meant to test my fill_web_form.py script</h2>
<br>
<br>
<h1>Test Form</h1>
<form action="/" method="post" name="login">
{{ render_field(form.test_form) }}<br>
<p><input type="submit" value="Sign In"></p>
</form>
</html>
Here is my init.py file
from flask import Flask, render_template
#import sqlite3
app = Flask(__name__)
#app.route('/')
def homepage():
return render_template("main.html")
if __name__ == "__main__":
app.run()
Here is my form.py file
from flask.ext.wtf import Form
from wtforms import StringField, BooleanField
from wtforms.validators import DataRequired
class LoginForm(Form):
test_form = StringField('test_form', validators=[DataRequired()])
Why do I keep getting a 500 error? I cant figure it out.
Run in debug mode app.run(debug=True) to see more information in browser.
You should import form and send to template. You may need secret_key to use csrf. etc.
from form import LoginForm
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
#app.route('/')
def homepage():
return render_template("main.html", form=LoginForm())
I trying to make a site that passes data from a web form to an sqlite database. I keep getting a 500 error. When I type the ip address and get to main.html, it displays the page with no errors, but when I submit the form I get a 500 error.
It doesn't give me the stacktrace is just says The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
It's hard to debug this because when I access the server through a browser, it doesn't give me details about the error. And when I run flask run in putty, it doesn't give me an error, it just gives me this
searching http://127.0.0.1 in my browser doesn't work, I'm guessing because flask run is running on the server and not on my computer.
Here is my code:
__init__.py
from flask import Flask, render_template
from forms import TestForm
import sqlite3
app = Flask(__name__)
#app.route('/')
def homepage():
return render_template("main.html", form=TestForm())
#app.route('/post', methods=['POST'])
def post():
conn = sqlite3.connect("sample.db")//If I remove these two lines
conn.close() //The code works without error
return render_template("test.html")
if __name__ == "__main__":
app.run(debug=True)
forms.py
from flask_wtf import Form
from wtforms import StringField, BooleanField
from wtforms.validators import DataRequired
class TestForm(Form):
test_form = StringField('test_form', validators=[DataRequired()])
main.html
<DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Sample Page</title>
<meta name="viewport" content="width=device-width"
initial=scale=1/>
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='favicon.ico') }}" rel="shortcut icon">
</head>
<h2>Hello, this site is meant to test my fill_web_form.py script</h2>
<br>
<br>
<h1>Test Form</h1>
<form action="/post" method="post" name="test">
{{ form.test_form(size=80) }}
<p>Form</p><br>
<p><input type="submit" value="Test Form"></p>
</form>
</html>
test.html
<DOCTYPE html>
</html>
<head>
<title>test</title>
</head>
<body>
<h1>Testing 123</h1>
</body>
</html>
**difference to the suggested repeat, my error stemmed from the following line being missing in the original code session['message']=request.form['message'] wherease in the suggested duplicate was missing the render_template component`
I am trying to create user sessions with Flask, I don't care about authentication. I just want a page where they enter their name, and then they are redirected to the main page. I tried to follow the example in this link here but I get a werkzeug.routing.BuildError. To summarise my python app is:
from flask import Flask, render_template
from flask import request, session, url_for,abort,redirect
app = Flask(__name__)
app.config['SECRET_KEY'] = 'F34TF$($e34D';
#app.route('/')
def home():
return render_template('index.html')
#app.route('/signup', methods=['POST'])
def signup():
session['username'] = request.form['username']
session['message']=request.form['message']
return redirect(url_for('message'))
#app.route("/message")
def message():
return render_template("message.html")
if __name__ == '__main__':
app.run(debug=True)
and index.html is:
{% extends "layout.html" %}
{% block content %}
<h1>Say something</h1>
<form method="post" action="{{ url_for('signup') }}">
<p><label>Username:</label> <input type="text" name="username" required></p>
<p><button type="submit">Send</button></p>
</form>
{% endblock %}
layout.html is:
<!doctype html>
<html lang="en">
<head>
<title>Say somthing</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
You are getting that error because you don't have a route called message and yet you are redirecting to it.
#app.route('/signup', methods=['POST'])
def signup():
session['username'] = request.form['username']
# Create a message route first
return redirect(url_for('message'))
Here's a sample route called message
#app.route("/message")
def message():
return render_template("message.html")