I have been unable to get the flash function to work in flask. Heres my code.
#!venv/bin/python3
from flask import Flask, flash
app = Flask(__name__)
app.config['SECRET_KEY'] = '12345'
#app.route('/')
def index():
flash('Hi')
return 'Hello'
if __name__ == '__main__':
app.run()
I expected this to flash a message saying hi but when I load the page no flash box appears. What am I not understanding here?
I think the main problem is that you're returning a string and not a render_template that handles the flash and converts it to a display message. Check out this documentation code here for an example of how to handle flashes
So I suggest trying: return render_template('index.html')
And then use the index.html file to set up your code that handles the flash message. I have a feeling that just returning a string, as you've done here, without somewhere for the code to understand the flash will give a null result.
#!venv/bin/python3
from flask import Flask, flash, redirect
app = Flask(__name__)
app.config['SECRET_KEY'] = '12345'
#app.route('/')
def index():
flash('Hi')
return redirect('index.html')
return render_template('index.html')
if __name__ == '__main__':
app.run()
ou can do following changes in your code import redirect and redirect it to any html page to show the flashed message.. in this case index.html
and in index.html page you have to use jinja template to get flash message and display it in page for that we use get_flashed_messages()
In index.html file add following code
<body>
{% for mesg in get_flashed_messages() %}
<h1>{{ mesg }}</h1>
{% endfor %}
</body>
It has been a while since the question was asked. I'll post my answer here since I got to this question somehow.
As Miguel Grinberg wrote in "Flask Web Development: Developing Web Applications with Python":
Calling flash() is not enough to get messages displayed; the
templates used by the application need to render these messages.
So anyone who have the same problem, just ensure, that you added the get_flashed_messages() function to the template and then displayed a message. For the reference you can look at:
Python Flask flash not working correctly,
and for sure Miguel Grinberg's book mentioned above, Chapter 4.
Hope this will be helpful.
Related
I'm new to Flask and trying to build my first simple app which takes a text input and upon the user clicking a button I want it to display the text that was entered.
My HTML page loads successfully and I can enter the text into the input.
However, when I click the button I get a new page showing the following error:
Internal Server Error
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.
My HTML:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>Predict Code</h1>
<form action="http://localhost:5000/predict" method="post">
<label form="description">Description:</label>
<input type="text" id="description" name="description">
<button type="submit">Predict Code</button>
</form>
<br>
<br>
{{ prediction_text }}
</body>
</html>
My flask app .py:
from flask import Flask, request, jsonify, render_template
# create the flask app
app = Flask(__name__)
# what html should be loaded as the home page when the app loads?
#app.route('/')
def home():
return render_template('app_frontend.html')
# define the logic for reading the inputs from the WEB PAGE,
# running the model, and displaying the prediction
#app.route('/predict', methods=['GET','POST'])
def predict():
# get the description submitted on the web page
a_description = request.form.values()
return render_template('Description entered: {}'.format(a_description))
# boilerplate flask app code
if __name__ == "__main__":
app.run(debug=True)
What have I done wrong and how can I fix it?
The problem is here:
#app.route('/predict', methods=['GET','POST'])
def predict():
# get the description submitted on the web page
a_description = request.form.values()
# THIS LINE:
return render_template('Description entered: {}'.format(a_description))
You're trying to render a template, but passing in a string, not a template.
If you want to return just the string, do this:
return 'Description entered: {}'.format(a_description)
If you look at the python error output you will see:
jinja2.exceptions.TemplateNotFound: Description entered: <generator
object MultiDict.values at 0x000001CEEEF83620>
EDIT
To answer the additional comment question. To get the value of the form post you will need to change your line from:
a_description = request.form.values()
to:
a_description = request.form.get('description')
I'm trying to submit a form, where the user can potentially upload several files, from which a background process is triggered that will take several minutes to complete. The issue I have currently is that when the user clicks the Submit button, nothing appears to happen for the user for several seconds while the files upload. Is there a way I can redirect to a (static*) holding page while the files upload and the processing happens, and then once the background process completes, this renders a new template?
Using Python 3.6.1 and Flask 0.12.2.
* I say static for now, but at some point in the future, I wish to use AJAX to update this page to give more information to the user
N.B. I have seen several similar questions, and the general answer is to use a module like Celery to perform async operations. Unfortunately, I do not have access to Celery as I cannot download new packages due to corporate policy.
main.py:
from flask import Flask, request, render_template, url_for, redirect
app = Flask(__name__, static_url_path = "/static", static_folder = "static")
#app.route("/", methods=['GET'])
def home():
return render_template("index.html")
#app.route("/in_progress", methods=['GET', 'POST'])
def in_progress():
if request.method == 'GET':
# Do the background processing here
return render_template('result.html') # This is the final part of the process
elif request.method == 'POST':
# Upload the files and do some pre-processing with the form
# This takes a couple of seconds so appears to not be doing anything for the user
# Want to render the GET 'in_progress.html' template at the top of this to give a better user experience
return render_template('in_progress.html') # Reloads same page using GET
index.html:
...some irrelevant HTML
<form action="{{ url_for('in_progress') }}" method="POST" id="form" name="form" enctype="multipart/form-data">
...other irrelevant HTML
I'm trying to develop a simple webapp that prompts the user for their address, requests forecast information from the NWS through their API, and prints out the results, but I'm running into some issues tying together the HTML and the Python script. I'm still new to programming in general and this is all a very rough copy at the moment, here's the relevant code:
weather.py:
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def home():
return render_template('weather.html')
#app.route('/forecast', methods=['GET', 'POST'])
def forecast():
if request.method == 'POST':
location = request.form['address']
# gets the weather information
return render_template('forecast.html', varying_forecast = forecast, wfo = wfo_info)
if __name__ == '__main__':
app.run(debug=True)
weather.html:
<form action="{{ url_for('forecast') }}" method="post">
Enter your address here: <input type="text" name="address"><br>
<input type="submit" name="submit" value="Get My Forecast!"><br>
</form>
When I try to go to 127.0.0.1:5000 I receive this error: "werkzeug.routing.BuildError: Could not build url for endpoint 'forecast'. Did you mean 'home' instead?" To the best of my knowledge this error occurs when url_for fails to find a route, but given that the forecast function does exist I'm confused where the error is coming from. Even after commenting out the form tag in the HTML the error persists. I tried getting rid of the "wfo" and "varying_forecast" in the return statement but that also didn't do anything. The only way to fix it is by setting the url_for of the action of the form to home, but I don't see any way to run the code in there and return the forecast information, considering it's already returning the home page. I'm having trouble understanding why it fails to display the weather.html page as written.
I've been testing whether routes exist using
def test_index(self):
r = self.app.get("/")
self.assertEqual(200, r.status_code, "Status code was not 'OK'.")
My template has a hyperlink to another page. Is there a way to test if this exists?
Well, if you are testing templates, every template you render is the result of a request to some route. If you render url's in a template using url_for(), then it will raise a BuildError if the url is pointing to a non existing route, and the server will return the status code 500. Therefore, you don't need to parse your templates manually for testing purposes if you just check the route instead.
Example:
from flask import Flask, render_template_string
app = Flask(__name__)
#app.route('/index')
def index():
return render_template_string("""
{{ url_for('index') }}
{{ url_for('blabla') }}
""")
def test_index(self):
r = self.app.get("/index")
self.assertEqual(200, r.status_code, "Status code was not 'OK'.")
This will result in a
routing.BuildError: Could not build url for endpoint 'blabla'. Did you mean 'static' instead? error, which makes your tests fail.
I hope this explanation is clear enough!
I have a python-flask app. And my source.py :
from flask import Flask, flash, redirect, render_template, request, session, abort
import os
from Modules.registry_bend.DockerImageReceiver import http_requester_v2_catalog, read_configurations
app = Flask(__name__)
#app.route('/v1')
def display_index():
return render_template('index.html')
if __name__ == "__main__":
# http_requester_v2_catalog("192.168.1.7", 5000)
app.secret_key = os.urandom(12)
app.run(debug=True, host='0.0.0.0', port=3150)
I run this source.py, and then open the browser and hit localhost:5000/v1.Then index.html appears. So, the challenge is, that a few seconds later I get some data, and I want to add them to index.html. How could it be possible? I have already called index.html once.
You can send the dynamic data to your HTML by sending context variables through the render template method.
flask.render_template(template_name_or_list, **context)
Renders a template from the template folder with the given context.
Parameters:
template_name_or_list – the name of the template to be rendered, or an iterable with template names the first one existing will be rendered
context – the variables that should be available in the context of the template.
Example -
return render_template('index.html', variable1=random.random(), variable2=random.random())
And in your HTML code you need to include these flask variables.
Example -
<p> {{variable1}} </p>
<p> {{variable2}} </p>
And whenever you refresh you html page in your browser. The new data will be displayed.