Basic Form In Flask Causing HTTP 400 - Python 3.5 - python

I am new and have spent hours trying to setup a form in Flask for Python 3.5. I want the user to be able to enter a temperature setpoint and click submit button, and have the value stored in a variable.
I have this code in a template file called index.html:
<html>
<body>
<p><font size="6">Jewell Hot-Tub Controller</font>
<br>
<font size="4">Water Temperature: {{water_temp}}</p>
<br>
<font size="4">Set Point: {{set_point}}</p>
<br>
<font size="4">Enter New Set Point:</p>
<form class="form-newtemp" method="get" action="/ChangeTemp">
<input type="text" id="new_sp" name="new_sp" size="5" placeholder="New Temp." required>
<input id="1submit" type="submit">
</form>
</body>
</html>
and this code in the "flask-test.py" file:
from flask import Flask, render_template, request
app = Flask(__name__)
app.debug = True
#app.route('/')
def index():
return render_template('index.html', water_temp='12345')
#app.route('/ChangeTemp', methods=['GET'])
def process():
new = request.form['new_sp']
return 'New set point is:' + new
Entering "27" in the textbox sends the browser to a 400 Bad Request page at:
http://127.0.0.1:5000/ChangeTemp?new_sp=27
Why does this change a bad request error, rather than returning the value? The tutorials I saw used POST, but I used GET, does this require different syntax?
Also, please let me know if anything is messy, or done wrong.
Thank you!
EDIT: I also tried "request.form.get('new-sp', new)" and this causes a 500 internal server error.

multiple ways to fix your problem. i guess the fastest way is:
<form class="form-newtemp" method="post" action="{{ url_for('process')}}">
and then
#app.route('/ChangeTemp', methods=['POST])
def process():
new = request.form['new_sp']
return 'New set point is:' + new
or you can go with not changing your template and:
#app.route('/ChangeTemp', methods=['GET'])
def process():
new = request.args.get('new_sp')
return 'New set point is:' + new

Related

Python Flask / HTML - what is the proper way of displaying an output after HTML form submission?

I am very new to web-development (first project) and have started playing around in Flask. The other day I made a very simple temperature converter which I was running on my local host. The page had a form input to type a value, two radio buttons with Fahrenheit and Celsius to define the system of the value, then a convert button. Here is a screenshot:
Here is my Flask code ("main.py"):
from flask import Flask, render_template
from flask import request, redirect
import temperature, convert, determine_system
app = Flask(__name__)
#app.route('/')
def html():
return render_template('index.html')
#app.route('/convert', methods = ['POST'])
def convert():
temp = request.form['temperature']
system = request.form['system']
new_temp, destination_system = determine_system.determine_system(temp, system)
return render_template('convert.html', temp=temp, system=system, new_temp=new_temp, destination_system=destination_system)
if __name__ == "__main__":
app.run()
As you can see, the first function called "html()" initially renders the "index.html" file and the function "convert()" is executed upon clicking the "Convert" button. There are a few other functions that I have in other .py files in the directory that convert the number to the new system.
Here is the body of my "index.html" code:
<body>
<div id="banner">
<h1>Temperature Converter</h1>
<p class="lead">Use this tool to convert temperature between measurement systems</p>
</div>
<form action="/convert" method="post" target="dummyframe">
<input type="text" name="temperature"></input>
<input type="radio" name="system" value="Fahrenheit">Fahrenheit</input>
<input type="radio" name="system" value="Celsius">Celsius</input>
<br>
<br>
<input type="submit" value="Convert"></input>
</form>
</body>
</html>
To display the converted temperature on the webpage, I currently have another HTML file called "convert.html" in my templates directory that is an exact copy of the "index.html" file, except it includes the following three lines of code in the body after the :
div id="output"></div>
<p class="output-statement">{{ temp }}° {{ system }} is equal to {{ new_temp }}° {{ destination_system }}</p>
</div>
In my Flask file ("main.py), I instruct the "convert()" function to render the "convert.html" template which includes the output statement in the code above:
return render_template('convert.html', temp=temp, system=system, new_temp=new_temp, destination_system=destination_system)
This then results in the following (notice the new web address):
I suspect that my way of outputting the converted temperature by redirecting to a new HTML file and web address (http://127.0.0.1:5000/convert) is not efficient or even the correct way of showing accomplishing this. What is the proper way to output something like this? Is there something I can add to the "index.html" file that would allow me to get rid of the "convert.html" file completely? If so, what would I change the last line of the "convert()" function in my Flask ("main.py") file to?
Thank you in advance and any links with more information on this concept are very appreciated!
Yes there is a more efficient solution where you do not need the convert.html:
This is what you will want in your main route. (note: I suggest renaming your route function to something like "index" or "temp" other than "html")
#app.route('/', methods=["GET","POST"])
def html():
output = ""
if request.method == "POST":
temp = request.form['temperature']
system = request.form['system']
new_temp, destination_system = determine_system.determine_system(temp, system)
output = f"{ temp}° { system } is equal to { new_temp }° { destination_system }"
return render_template('index.html', output=output)
Make sure to import request. using: from flask import request
and in your index.html you will now have:
<div id="output"></div>
<p class="output-statement">{{output}}</p>
</div>
And make sure to change form action to action="#" or action=""

The method is not allowed for the requested URL: Using Flask POST Method

First of all, I am very new to this so I hope I can explain myself the best I can.
I have a project in college in which we are using Flask to create a web app.
We need to gather inputs from users and then predict certain values with a model I have created, saved with Pickle and load it in my app .Now when I access to my page , I can see the home page shows and I am able to enter inputs but then the 'predict' page is not showing and giving me the error 'The method is not allowed for the requested URL'. I have consulted and follow different approaches to do this, for example from this article: https://www.kdnuggets.com/2019/10/easily-deploy-machine-learning-models-using-flask.html and this https://towardsdatascience.com/deploy-a-machine-learning-model-using-flask-da580f84e60c but still not able to make it work.
Any help, tips or good tutorials would be so much appreciated! Thank you so much in advance and sorry for this long post.
My project folder has the following contents:
app.py
model.pkl(This is my model saved on my disk using Pickle)
Powerproduction dataset.csv( the original dataset)
request.py
model.py ( this is the model )
import numpy as np
from flask import Flask, request, jsonify, render_template
import pickle
app = Flask(__name__)
model = pickle.load(open('model.pkl', 'rb'))
#app.route('/')
def home():
return render_template('index.html')
#app.route('/predict',methods=['POST'])
def predict():
int_features = [float(x) for x in request.form.values()]
final_features = [np.array(int_features)]
prediction = model.predict(final_features)
output = round(prediction[0], 2)
return render_template('index.html', prediction_text='Power output should be $ {}'.format(output))
#app.route('/results',methods=['POST'])
def results():
data = request.get_json(force=True)
prediction = model.predict(final_features)
output = prediction[0]
return jsonify(output)
if __name__ == "__main__":
app.run(debug=True)`
import requests
url = 'http://127.0.0.1:5000/'
r = requests.post(url,json={'wind speed':})
print(r.json())
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import pickle
dataset = pd.read_csv('Powerproduction dataset.csv')
X = dataset.loc['speed']
y = dataset.loc['power']
from sklearn.linear_model import LinearRegression
regressor = LinearRegression()
regressor.fit(X.values.reshape(-1,1), y)
pickle.dump(regressor, open('model.pkl','wb'))
model = pickle.load(open('model.pkl','rb'))
print(model.predict(np.array([[34.00]]))[0])
<head>
<meta charset="UTF-8">
<title>Wind speed and power output prediction</title>
</head>
<body style="background: #000;">
<h1>Power output predictions</h1>
<!-- Main Input For Receiving Query to our ML -->
<form action="{{ url_for('home')}}"method="post">
< />
<input type="text" name="wind speed" placeholder="wind speed" required="required" />
<button type="submit" class="btn btn-primary btn-block btn-large">Predict power output</button>
</form>
<br>
<br>
{{ prediction_text }}
</div>
</body>
</html>
Your action references your home route:
action="{{ url_for('home')}}
You want this to point to your predict route:
action="{{ url_for('predict') }}"
You should also have a space after " (but most browsers parse this correctly):
action="{{ url_for('predict') }}" method="post">
The empty < /> in your index.html should also be removed.
I'd also fix the indentation, usually you don't indent after #app.route(..) and make sure you have an empty line between function end and your next route to make it more readable (there is a standard named PEP-8 that defines how Python code should look - Pycharm and other editors will usually give you hints if you don't conform):
#app.route('/predict',methods=['POST'])
def predict():
..
#app.route(...)
def foo():
..

Return button in flask

I'm learning to use Flask but I did not found a "easy solution" (by "easy solution" I mean easy for my noob level, few codes line) for this so I'm asking here for help.
How I can create a "back" button on the new generated page in flask?
This is my code:
calculator.py
from flask import Flask, request, render_template
app = Flask(__name__)
#app.route("/")
def my_form():
return render_template("calc.html")
#app.route("/", methods=['POST'])
def my_form_post():
num_1 = request.form['Number 1']
num_2 = request.form['Number 2']
result = int(num_1) + int(num_2)
render = render_template("calc_result.html")
#return render_template("calc_result.html")
return "The result from " + str(num_1) + " plus " + str(num_2) + " is: " + str(result) + "."
app.run(host='127.0.0.1', port=5000)
calc.html
<html>
<body>
<form method = "POST">
<input name = "Number 1">
<input name = "Number 2">
<input type = "submit">
</body>
</form>
The code is working, is receiving the numbers and doing the math but the problem is, I'm not able to generate a "back" button in the new generated page with the result.
If I put for example 10 + 10 in the calc.html, I will receive:
The result from 10 plus 10 is: 20.
I would like to put a "back" button on this page or learn how to generate a new button in the new gelerated page, so I would receive something like:
The result from 10 plus 10 is: 20.
Back
Sorry the english.
Edit:
This is what user see on the first page:
What user see in first page
After put the two numbers to sum, they see:
Result page
I want allow user to come back to first page and be able to do another sum.
In both pages the link are the same: http://127.0.0.1:5000/
in your 'calc_result.html' file, make a link or button and use the 'url_for' command to bring you back to your 'calc.html' page. Flask allows you to insert Python code into your HTML via jinja templates. Check out the quickstart guide here. So:
Back
You can use the following code:
<button onclick="goBack()">Go Back</button>
<script>
function goBack() {
window.history.back();
}
</script>
Please refer this.
<a href="/">
<form action="/">
<input class="btn" type="button" value="HOME" />
</form>
</a>

Changing values using POST method in FLASK?

I'm new in StackOverflow and Python. I'm trying to make a basic application where I have my < form > tag, my flask app, and my .txt. I'm trying to change values but it's not working or I don't know why it's not working. Could any of you give me a hand?
Python Flask:
from flask import Flask,render_template,flash,request,redirect
import os
app = Flask(__name__)
from lines import get_line
#app.route('/', methods=['POST'])
def change_line():
search_line= "this"
try:
for line in this.input(os.path.join(APP_STATIC, u'line.txt'),inplace=1):
if search_line in line:
x = line.replace(search_line,search_line + "\n" + request.form.get(u'this'))
print (x)
else:
print (x)
except BaseException as e:
print e
return render_template('line.html')
#app.route('/')
def showLine():
line = get_line()
return render_template('line.html', line=line)
if __name__ == '__main__':
app.run()
HTML:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Change the value of this line</title>
</head>
<body>
<form method="post" name="test">
<h4>Chaging Values with POST Method</h4>
<div class="col-sm-9">
<label class="col-sm-3 col-sm-3 control-label">I want to change : </label>
<input type="text" class="form-control" name="address" value="{{ line }}">
</div>
<input type="submit" value="Save Changes!">
</form>
My .txt file:
I want to change this.
It's returning the value of "this".
Basically when I run my app it's displaying "this" when I try to edit for "Hello" it's returning me an error:
Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) Line
Found! : this.
127.0.0.1 - - [21/Oct/2016 13:09:07] "GET / HTTP/1.1" 200 - global name 'this' is not defined
127.0.0.1 - - [21/Oct/2016 13:09:30] "POST / HTTP/1.1" 200 -
My output:
Please click here to see my output
I'm sorry if this is a silly question, or if this was answered before, but I've been browsing for an answer for time and I have found nothing about this, I've tried different codes but not working, been watching youtube videos and everything.
If someone know the solution would be really helpful for me.
It's for learning and Python School. Thanks!
Working on Python 2.7
EDIT
I updated code with the suggestions below but it's not working yet.
it's not overwriting my "this" with replace.
from flask import Flask,render_template,flash,request,redirect
import os
app = Flask(__name__)
from lines import get_line
import fileinput
#app.route('/', methods=['POST'])
def change_line():
search_line= "this"
try:
for line in fileinput.input(os.path.join(APP_STATIC, u'line.txt'),inplace=1):
if search_line in line:
x = line.replace(search_line,search_line + "\n" + request.form.get(u'asd'))
print (x)
else:
print (x)
except BaseException as e:
print e
return render_template('line.html')
#app.route('/')
def showLine():
line = get_line()
return render_template('line.html', line=line)
if __name__ == '__main__':
app.run(debug=True)
this.input(os.path.join(APP_STATIC, u'line.txt'),inplace=1):
should be
fileinput.input(os.path.join(APP_STATIC, u'line.txt'),inplace=1):
(you will also need import fileinput)
you need to change this because this.input doesnt mean anyhthing to python ... it has no idea what this is ...
global name 'this' is not defined
as an aside you should really run with app.run(debug=True) while developing

Having trouble understanding CherryPy

I read through the tutorial on the cherrypy website, and I'm still having some trouble understanding how it can be implemented in a modular, scalable way.
Could someone show me an example of how to have cherrypy receive a simple http post to its root, process the variable in some way, and respond dynamically using that data in the response?
from cherrypy import expose
class Adder:
#expose
def index(self):
return '''<html>
<body>
<form action="add">
<input name="a" /> + <input name="b"> =
<input type="submit" />
</form>
</body>
</html>'''
#expose
def add(self, a, b):
return str(int(a) + int(b))
if __name__ == "__main__":
from cherrypy import quickstart
quickstart(Adder())
Run the script and then open a browser on http://localhost:8080
Are you asking for an example like this?
http://www.cherrypy.org/wiki/CherryPyTutorial#ReceivingdatafromHTMLforms
It receives input from forms.
You can return any text you want from a CherryPy method function, so dynamic text based on the input is really trivial.

Categories