Flask request.form not retrieving any data - python

I'm posting data to the following Flask view using an HTML form. For some reason, the server is never created. I've confirmed that the create_server method works from the interpreter. Another form I'm using to log in works. Why isn't this working?
#app.route('/add-server/', methods=['GET', 'POST'])
def add_server_view():
if request.method == 'post':
server_name = request.form['server_name']
create_server(server_name)
return redirect(url_for('index')
return render_template('add_server.html')
<form method=post>
<input name=server_name>
</form>

request.method will be in all caps and the comparison is case sensitive.
if request.method == 'POST':
This code in Werkzueg forces the method name to uppercase for consistency.

Related

User input from python flask to be sent to ansible variable

Say I have an example flask app which basically is a small webform that would take in user input data called applet.py.(The code is taken from a online blog that shows an example flask app build).
from flask import Flask,render_template,request
app = Flask(__name__)
#app.route('/form')
def form():
return render_template('form.html')
#app.route('/data/', methods = ['POST', 'GET'])
def data():
if request.method == 'GET':
return f"The URL /data is accessed directly. Try going to '/form' to submit form"
if request.method == 'POST':
form_data = request.form
return render_template('data.html',form_data = form_data)
app.run(host='localhost', port=5000)
The input is captured in this below form.
<form action="/data" method = "POST">
<p>Name <input type = "text" name = "Name" /></p>
<p>City <input type = "text" name = "City" /></p>
<p>Country <input type = "text" name = "Country" /></p>
<p><input type = "submit" value = "Submit" /></p>
</form>
If I were wanting to send this received user input into ansible variables and then trigger the ansible script to run and execute the playbook based on the given variables. How can I do that? I have googled a lot around this, couldn't find a suitable example that fits my use case. (Disclaimer, not very knowledgeable about both flask and ansible, learning as I do). Appreciate help, reference and advice.
You can use the ansible_runner module to run your playbook (docs).
import ansible_runner
#app.route('/data/', methods = ['POST', 'GET'])
def data():
if request.method == 'GET':
return f"The URL /data is accessed directly. Try going to '/form' to submit form"
if request.method == 'POST':
form_data = request.form.to_dict()
r = ansible_runner.run(playbook='test.yml', extravars=form_data)
# check ansible return code
if r.rc != 0:
abort(400, 'Ansible error')
return ('', 204)
If your playbook takes some time to run you might be better adding the job of running it to a queue and processing it separately.

How to make a redirect button in Flask template

I am trying to make a web-app using flask, and I am having a problem redirecting to another page/route that I have in my app.py file. I also set up a HTML template for the other (login) page.
Here is my code in the main app.py:
#app.route('/', methods=['GET', 'POST'])
if request.method == 'GET':
pass
if request.method == 'POST':
pass
return render_template('index.html', passable=passable)
#app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
name = request.form.get('username')
post = request.form.get('password')
# still need to complete
return render_template('login.html')
I have imported all the relevant modules (I think).
In my Index.html file, I have a button, which I would like it to redirect to my login.html page. Currently I am doing something like this:
<button type="submit" onclick='{{Flask.redirect(url_for(login))}}' value="editor">
Whenever I launch the page (locally) i get this error.
jinja2.exceptions.UndefinedError
jinja2.exceptions.UndefinedError: 'Flask' is undefined
How do I make my button redirect to the "login" flask route?
If you want your form to submit to a different route you can simply do <form action="{{ url_for('app.login') }}">.
If you just want to put a link to the page use the <a> tag.
If you want to process the request and then redirect, just use the redirect function provided by flask.
<a href="{{url_for(app.login)}}" >Login</a>

How can I create a session from user input?

Disclaimer: Yes I know this might not be the right way to do it, but I just need a quick and easy fix and in this case I prefer the quick and dirty way.
I have a login.html like this:
<form method="POST" class="login-form" action="/login">
<input type="text" name="code">
<input type="submit" value="Submit">
</form>
I have two types of users who will visit this page. First type of users will have "code_A", second type of users will have "code_B". Depending on which code they will type into the form field they will be redirected to gallery or gallery2.
This is my routes.py:
code_A = "code_A"
code_B = "code_B"
#app.route("/login", methods=['GET', 'POST'])
def login():
if 'code_A' in session:
redirect(url_for('gallery'))
elif 'code_B' in session:
redirect(url_for('gallery2'))
elif request.method == 'POST':
code_post = request.form['code']
if code_post == code_A:
session['code_A'] = code_A
return redirect(url_for('gallery'))
elif code_post == code_B:
session['code_B'] = code_B
return redirect(url_for('gallery2'))
else:
return render_template("login.html")
else:
return render_template("login.html")
return render_template("login.html")
#app.route("/gallery")
def gallery():
if 'code_A' not in session:
return redirect(url_for('login'))
else:
return render_template('gallery.html')
#app.route("/gallery2")
def gallery2():
if 'code_B' not in session:
return redirect(url_for('login'))
else:
return render_template('gallery2.html')
I though I could simply take the input from the form and create a session based on the input. If the right code is in the session, the user should be redirected to gallery or gallery2, depending on the session. But with this code I always get redirected to login.html and no session is created. How do I pass the input from the form to the routes.py and create a session from it. I mean it cannot be that hard, or is it?
I am thankful for every suggestion, because I am loosing my mind over it. Thanks and best regards!

BadRequestKeyError [duplicate]

This question already has answers here:
Get the data received in a Flask request
(23 answers)
Closed 4 years ago.
Multiple questions have been asked with a similar error on SO. I have tried all of the solutions but still keep getting a beautiful error:
werkzeug.exceptions.HTTPException.wrap..newcls: 400 Bad Request: KeyError: 'username'
Below is my html form:
<form action='/login' method = "GET">
<label>Name: </label>
<input name="username" type="text">
<input type="submit" name='submit' value='submit'>
</form>
Here is the function that deals with the form data:
#app.route('/login', methods = ['GET'])
def login():
if request.method == "GET":
un = request.form['username']
return un
I have learned Bottle and transitioning towards Flask.
So far, I have tried the following:
1) GET to POST
2) request.form.get('username', None)
3) Add POST reason to the function route without any rhyme or reason.
Can somebody help me out?
You need to change the method (GET to POST) in the html file and add the method in the decorator #app.route too. Do not forget that in this case a return (GET) is required to render the html file.
#app.route("/login", methods = ['GET', 'POST'])
def login():
if request.method == "POST":
# import pdb; pdb.set_trace()
un = request.form.get('username', None)
return un
return render_template('form.html')
Tip: Learn about pdb to debug your programs more easily.
https://realpython.com/python-debugging-pdb/
https://docs.python.org/3/library/pdb.html
no need to change your form action method. but when you use GET method for sending form data your data is transmitted as URL variables and you need to read data this way:
if flask.request.method == 'GET':
username = flask.request.args.get('username')
and if you change the method to POST, read content as below:
if flask.request.method == 'POST':
username = flask.request.values.get('username')

Flask redirects to wrong view when redirecting to index

I keep running into this strange issue that I can't seem to figure out a solution for. I cannot copy and show all of my code in it's entirety here, but I will try to outline the general structure of my flask app to present my issue.
(Let's ignore all of the content in the /static folder and my helper modules)
I have 3 main views, let's call them viewA, viewB, and index:
viewA.html
viewB.html
index.html
viewA and viewB both display two forms, but with different content (i.e. viewA displays form1 & form2, and viewB also displays form1 & form2).
A simplified version of my script code is as follows:
#imports
from flask import Flask, render_template, session, redirect, url_for, request
from flask_wtf import FlaskForm
#etc. etc.
app = Flask(__name__)
app.config['SECRET_KEY'] = 'blah blah blah'
manager = Manager(app)
bootstrap = Bootstrap(app)
moment = Moment(app)
class FormOne(FlaskForm):
sample_field = StringField('Sample Field:')
class FormTwo(FlaskForm):
other_field = StringField('Other Field:', validators=[Required()])
submit = SubmitField('Submit')
class UploadToA(FlaskForm):
content= StringField('Content to send to view A:', validators=[Required()])
submit = SubmitField('Submit')
class UploadToB(FlaskForm):
content= StringField('Content to send to view A:', validators=[Required()])
submit = SubmitField('Submit')
#app.route('/ViewA', methods=['GET', 'POST'])
def view_a():
"""
A lot of data manipulation
"""
form1 = FormOne()
form2 = FormTwo()
if request.method == 'GET':
"""
populate forms with content
"""
if request.method == 'POST':
if form2.validate_on_submit();
"""
clear session variables
"""
return redirect(url_for('index'), code=302)
return render_template('viewA.html', form1=form1, form2=form2)
#app.route('/ViewB', methods=['GET', 'POST'])
def view_b():
"""
A lot of data manipulation
"""
form1 = FormOne()
form2 = FormTwo()
if request.method == 'GET':
"""
populate forms with content
"""
if request.method == 'POST':
if form2.validate_on_submit();
"""
clear session variables
"""
return redirect(url_for('index'), code=302)
return render_template('viewB.html', form1=form1, form2=form2)
#app.route('/', methods=['GET', 'POST'])
def index():
"""
Some data manipulation
"""
formA = UploadToA()
formB = UploadToB()
if formA.validate_on_submit()':
"""
pull content from form A
create some session variables
"""
return redirect(url_for('view_a'))
if formB.validate_on_submit()':
"""
pull content from form B
create some session variables
"""
return redirect(url_for('view_b'))
return render_template('index.html', formA=formA, formB=formB)
if __name__ == '__main__':
manager.run()
Now the issue at hand I am having here is that for some strange reason when I'm in 'viewA.html' and I submit my form, I SHOULD be redirected back to 'index.html' but for some strange reason it redirects me to 'viewB.html'. Furthermore, the opposite also holds true: when i'm in 'viewB.html' and I submit my form, I SHOULD also be redirected back to 'index.html' but it redirects me to 'viewA.html'. Yet, if I am in either viewA or viewB, I have no issues of going back to the index view if I manually enter the url into my browser.
Any ideas as to why I might be running into this issue?
Thanks in advance :)
I have finally figured out the source of my problem. It turns out that in my 'viewA.html' template file, I had the following in my < form > tag:
<form class="form form-horizontal" method="post" role="form" action="{{url_for('index')}}">
And the problem all lies in that last part:
action="{{url_for('index')}}"
As a result, everytime I would submit form2 in viewA.html it would create a post request for my index page rather than a post request for the viewA.html page (which caused a redirect to the wrong view). Thus, by simply removing the action attribute (action="{{url_for('index')}}"), I was able to solve my problem!
Since the full code isn't here, I can't confirm this for sure, but what I think is happening is this:
You open form A
You submit form A
It sends a redirect to /index
It sends a redirect to /FormB
if formB.validate_on_submit():
return redirect(url_for('view_b'))
This is probably sending a redirect to View B. Try changing that last line to something like return something_else and seeing if it sends that after submitting form A.

Categories

Resources