Executing python script with flask, from button - python

I'm trying to execute a def/python script from flask, when clicked on button... but can't seem to figure it out.
Here's my Python Code
from flask import Flask, redirect, url_for, render_template, request
import webbrowser
app = Flask(__name__)
#app.route("/")
def home():
return render_template("index.html")
def contact():
if "open" in request.form:
print("Test")
elif "close" in request.form:
print("Test 2")
return render_template('contact.html')
if __name__ == "__main__":
app.run(debug=True)
And here is my HTML Code
<html>
<head>
<title>Home page</title>
</head>
<body>
{% extends "base.html" %}
{% block title %}Home Page{% endblock %}
{% block content %}
<h1>Test</h1>
<input type="submit" name="open" value="Open">
<input type="submit" name="close" value="Close">
{% endblock %}
</body>
</html> ```

I don't know what is in {% block content %} but you need to have a form in order to call backend where you provide the url route that you want to call and the method you want to use (usually with forms it's POST). Also in the /contact endpoint you need to provide #app.route('/contact') and that it would accept POST request #app.route('/contact', methods=['POST']). Modify your python and HTML to look like this:
from flask import Flask, redirect, url_for, render_template, request, jsonify
import webbrowser
app = Flask(__name__)
#app.route("/")
def home():
return render_template("index.html")
#app.route('/contact', methods=['POST'])
def contact():
result = False
if "open" in request.form:
result = activate_lamp() # expecting True as a result of function
elif "close" in request.form:
result = deactivate_lamp()
return jsonify({'result': result}) # expecting True as a result of function
if __name__ == "__main__":
app.run(debug=True)
<html>
<head>
<title>Home page</title>
</head>
<body>
<h1>Test</h1>
<form action="{{ url_for('contact') }}" method="post">
<input type="submit" name="open" value="Open">
<input type="submit" name="close" value="Close">
</form>
</body>
</html>
The jsonify will return an object to the front end with default 200 response code. Then you can either do something with it or ignore it. The idea is that in the route you can call other functions, but you must return a valid HTTP response to the front-end, e.g. jsonify, or plain return '', 200 might be enough.

Related

Passing radio button value on page refresh in Flask

I am trying to build a simple Flask app in Python with two radio buttons and a "refresh" button, where, on clicking on the refresh button, the page reloads and displays the radio button selection on the previous page.
Routes.py:
#app.route("/")
def display():
return render_template("index.html", choice=choice)
if request.form['submit'] == 'Refresh':
choice= request.form.get("Choice")
return redirect(url_for('/'))
index.html:
<html>
<head>
<title>Choice</title>
</head>
<body>
<h2>Choice</h2>
<hr>
{{choice}}<br>
<form action="">
<input type="radio" name="Choice" value="Choice1"><span>Choice 1/span><br/>
<input type="radio" name="Choice" value="Choice2"><span>Choice 2</span>
<input type="submit" name="refresh" value="Refresh">
</form><br>
</form> </body>
</html>
Apply the below changes and check if it works!
render_template, request, redirect, url_for was used but not imported. Try to import them.
from flask import Flask, render_template, request, redirect, url_for
To retrieve POST data, you can use request.form.
To retrieve GET data, you can use request.args.
Try the below code if you want to use request.args:
#app.route("/")
def display():
choice = request.args.get('Choice','None Selected')
return render_template("index.html", choice=choice)
if request.args.get('refresh') == 'Refresh':
return redirect(url_for('display',Choice=choice))
Try the below code if you want to use request.form:
#app.route("/",methods = ['POST', 'GET'])
def display():
if request.method == 'GET':
choice = request.args.get('Choice','None Selected')
return render_template("index.html", choice=choice)
if request.method == 'POST':
choice= request.form.get("Choice")
return redirect(url_for('display',Choice=choice))
In index.html add <form action="" method="POST"> to send the form data

Flask raising 405 error when submitting a form

I have just started to learn flask but I am stuck with this 405 error
# Weather App using Flask
## imports
import main
from flask import Flask
from flask import render_template
from flask import request
app = Flask(__name__)
## initalisation
#app.route('/')
def main_page(methods=["GET", "POST"]):
if request.method == "POST":
city = request.form("city")
print(city)
return render_template("main.html")
if __name__ == "__main__":
app.run(debug=True)
the main.html is
{% extends "base.html" %}
{% block content %}
<form method="POST">
<p><input type="text" name="city"></p>
<p><input type="submit" value="Submit"></p>
</form>
{% endblock %}
the POST is in the methods argument, but I cannot pinpoint where the error is
thanks in advance
Instead of having the methods list in the view function's parameters, you should have it in the brackets that follow your decorator, like so:
#app.route('/',methods=["GET","POST"])
def main_page():
# your view function
This will allow this route to be accessed through both GET and POST requests.

Method not allowed for requested URL

I am trying to upload file from my flask site,but it keeps returning the error
method is not allowed for the requested URL. Even my teacher does not have the answer to this question. According to him he has never seen this error. really appreciate your help
my HTML file is as follows
<!DOCTYPE html>
<html lang="en">
<title> Data Collector App </title>
<head>
<link href="../static/main.css" rel="stylesheet">
</head>
<body>
<div class="container">
<h1>Data Collector</h1>
<form action={{url_for('index')}} method="POST" enctype="multipart/form-data">
<input type="file" name="file">
<button type="submit">Submit</button>
</form>
</div>
</body>
</html>
Python srcipt is
from flask import Flask, render_template, request, send_file, url_for
import pandas
from werkzeug.utils import secure_filename
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/index')
def upload():
if method == "POST":
file=request.files['file']
file.save(secure_filename("new"+file.filename))
return render_template('index.html')
if __name__ == "__main__":
app.run(debug = True)
Add any allowed methods to a route in the decorator, e.g.
#app.route('/index', methods=['POST', ...])
EDIT:
You should probably also check on the method field of request instead of just method.
if request.method == 'POST':
By default routes only accept the GET method. If you want your route to answer to other methods, pass a custom methods parameter to #app.route as follows
#app.route('/', methods=['GET', 'POST',])
...
#app.route('/index', methods=['GET', 'POST',])
...
Source https://flask.palletsprojects.com/en/1.1.x/quickstart/#http-methods

Flask, Passing User Entered Data Between Views

Problem transferring variables across views I tried using sessions and could not get the connection to work. Say I have two pages, a home and page2. I have a flask app that will take user input from the home and print out input on page2.
For example, if you start my app, you will see this as the home page:
This part works fine, I am able to enter a value.
What I want to happen next, is after you click submit, page2 is generated showing what was just entered:
Whatever string value was entered on home should show up in the highlighted portion.
I have the following app.py file:
from flask import Flask, render_template, request, session
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def home():
stringval = ''
if request.method == 'POST' and 'stringval' in request.form:
stringval = request.form.get('stringval')
session["stringvalue_topass"] = stringval
return render_template('page2.html', stringval = stringval)
return render_template("home.html")
#app.route('/page2', methods=['GET', 'POST'])
def page2():
stringvalue_get = session.get('stringvalue_topass')
return render_template('page2.html', stringvalue_get = stringvalue_get)
if __name__ == '__main__':
app.run(debug=True)
The following home.html:
<!doctype html>
<h1>Enter Value </h1>
<div class="main">
<form class="pure-form" method="POST" action="/page2">
stringval:<br>
<input type="text" name="stringval"><br>
<button type="submit" class="pure-button pure-button-primary" value="Submit">Submit!</button>
</form>
</div>
</body>
And the following page2.html
<!doctype html>
<h1>You have selected </h1>
<div class="main">
{% if stringvalue_get %}
<pre>
{% print(stringvalue_get) %}
</pre>
{% endif %}
</div>
</body>
Okay, there are a few issues here. Firstly, the action attribute of your form in home.html is set to "/page2". This means that when the form is submitted, the POST request is going to the /page2 endpoint rather than to the /home endpoint, where you have written the code for handling the form submission. We can fix this by just deleting the action attribute, as this means the form will post to then endpoint that loaded it - in this case /home.
Secondly, Flask sessions cannot be used without setting a secret key to encrypt the session. This can be done by assigning a value to app.secret_key, like so:
app = Flask(__name__)
app.secret_key = b"my_secret_key"
Finally, instead of passing the string to the template like so: render_template('page2.html', stringval = stringval), (note also that this should be stringval_get = stringval), you can access the session object directly from templates already. So, in all, we can change your application code to:
app.py:
from flask import Flask, render_template, request, session
app = Flask(__name__)
app.secret_key = b"my_secret_key"
#app.route('/', methods=['GET', 'POST'])
def home():
if request.method == 'POST' and 'stringval' in request.form:
session["stringvalue_topass"] = request.form.get('stringval')
return render_template('page2.html')
return render_template("home.html")
#app.route('/page2', methods=['GET', 'POST'])
def page2():
return render_template('page2.html')
And your templates to:
home.html:
<!doctype html>
<h1>Enter Value </h1>
<div class="main">
<form class="pure-form" method="POST">
stringval:<br>
<input type="text" name="stringval"><br>
<button type="submit" class="pure-button pure-button-primary" value="Submit">Submit!</button>
</form>
</div>
</body>
page2.html:
<!doctype html>
<h1>You have selected </h1>
<div class="main">
{% if 'stringvalue_topass' in session %}
<pre>
{% print(session["stringvalue_topass"]) %}
</pre>
{% endif %}
</div>
</body>

Flask set_cookie does not set cookie

I've been having this big issue with my python code. I'm trying to set a cookie, and sometimes the cookie gets set, but most of the time it just doesn't. I've been trying to print out the value of the cookie, and quite often (most of the time) it's None. Can anyone please help me find out what I've done wrong? I appreciate all help. Thanks in advance
This is my run.py file
from flask import Flask, request, url_for, redirect, render_template, make_response
import os
app = Flask(__name__)
app.secret_key = os.urandom(16)
#app.route('/')
#app.route('/home')
def home():
return render_template('home.html')
#app.route('/login', methods=['POST'])
def login():
user = request.form.get('username')
password = request.form.get('password')
response = make_response('')
response.set_cookie('id', 'test', domain='127.0.0.1')
return redirect('home')
if __name__ == '__main__':
app.run('127.0.0.1', debug=True)
And below here is my html code. (templates/home.html)
<html>
<head>
<title>Login Page</title>
</head>
<body>
<h1>Please login</h1>
<form method="POST" action="{{ url_for('login') }}">
<input type="text" name="username">
</br>
<input type="password" name="password">
</br>
<input type="submit">
</form>
</body>
</html>
what happens if you change your the part of your code to this
response = make_response(redirect('/home')
response.set_cookie('id', 'test')
return response

Categories