Flask request.files is empty [duplicate] - python

This question already has answers here:
Post values from an HTML form and access them in a Flask view
(2 answers)
Closed 3 years ago.
much like this question, I'm trying to follow the simple Flask tutorial for file upload to a flask server. In my specific case, I'm trying to upload an XML file.
The (simplified) HTML I'm using is:
<form action="" method="post" enctype="multipart/form-data">
<input type="file">
<input type="submit" value="Let's go!">
</form>
The request is correctly handled by a if request.method == 'POST': block, so I put in some print statements to troubleshoot:
print('request.method', request.method)
print('request.args', request.args)
print('request.form', request.form)
print('request.files', request.files)
and the result was the following:
request.method POST
request.args ImmutableMultiDict([])
request.form ImmutableMultiDict([])
request.files ImmutableMultiDict([])
What am I doing wrong? I can provide more complete source code if needed.

As always, I found the answer mere minutes after posting this question. I'm answering here to hopefully help someone else.
The problem was that my file input had no name attribute. Thanks to Ben here I was able to fix this problem by adding a name attribute to the file input, and now the file upload is being processed correctly.

Related

How is flask able to access login.html? [duplicate]

This question already has answers here:
Sending data from HTML form to a Python script in Flask
(2 answers)
Closed 1 year ago.
I am trying to learn flask.
My login.html file-
<html>
<body>
<form action = "http://localhost:5000/login" method = "post">
<table>
<tr><td>Name</td>
<td><input type ="text" name ="uname"></td></tr>
<tr><td>Password</td>
<td><input type ="password" name ="pass"></td></tr>
<tr><td><input type = "submit"></td></tr>
</table>
</form>
</body>
</html>
And my main.py file has this-
#app.route('/login',methods = ['POST'])
def login():
uname=request.form['uname']
passwrd=request.form['pass']
if uname=="ayush" and passwrd=="google":
return "Welcome %s" %uname
I am not able to understand how is this able to access login.html without specifying. Also also please explain what is the code in main.py means.
You have to specify the 'html' in flask to access it, however, if you open the html file in browser this will still work since its action is aimed directly at your flask server.
the code of your main.py says that if the in the form sent the data 'uname' and 'pass' are respectively 'ayush' and 'google', the code sends back to the browser a text indicating: "Welcome ayush"
If you want to directly implement the html in your flask web server, you have to create the function and put your html code in templates folder.
from flask import render_template
...
#app.route('/', methods=['GET'])
def code():
return render_template('index.html', name='')
So you can access with http://localhost:5000/ now

Flask and Retrieving data from HTML [duplicate]

This question already has answers here:
Sending data from HTML form to a Python script in Flask
(2 answers)
Closed 1 year ago.
i am relatively new to Flask/Python/HTML so please excuse my language.
Basically I am trying to retrieve the "name" field with request.form.get that was inputted in my HTML page. The name field was generated with a for loop in jinja. When i hit the checkbox, and click submit, i expect the request.form.get to retrieve the "name" field that was in that specific check boxes' data. However, when i test out the data, I get a 404 error that says NONE for the request.form.get value. I'm not sure where I am going wrong. I suspect it might be what I am plugging in as the name for request.form.get.
On my flask side:
#app.route("/recipedata", methods=["GET","POST"])
def recipedata():
if request.method == 'POST':
food = request.form.get("{{value.id}}")
On HTML side:
{% for value in foodinfo.results %}
<form action="/recipedata" method = "POST">
<input type="checkbox" name="{{value.id}}" value={{value.id}}>
<input type=text placeholder="{{value.id}}">
<input type="submit"> Go to Recipe info
</form>
{% endfor %}
The 2nd line in my form tag with type text was used to test whether my value.id was printing correctly in Jinja, and indeed it was. Additionally, for clarification, foodinfo is passed as a .json() object with nested dictionary key/values. Value.id allows me to access that dict's value at key 'id', I believe.
Thank you!
I don't think your function definition of recipedata() is valid as per python syntax. You need to indent code in python to preserve scope information. You can see more here.
Try with following function definition.
def recipedata():
if request.method == 'POST':
food = request.form.get("{{value.id}}")
I'm not sure if HTML part is causing any trouble.

view multipart form request parameter values using flask [duplicate]

This question already has answers here:
Get the data received in a Flask request
(23 answers)
Closed 6 years ago.
I'm uploading a file to my flask backend and I can't figure out how to access the parameter values in the multipart form.
I can access the uploaded file easily by doing file = request.files['file'] but can't figure out a way to get the parameter values.
I've tried the following but haven't had any luck:
print(request.data['share'])
print(request.data['title'])
print(request.get('share'))
print(request.get('title'))
Most form inputs can be retrieved as follows:
request.form.get("fieldname")
Files can be accessed via
request.files.get("fieldname")
Where the fieldnames are the name attribute in the HTML.
Keep in mind that, just because there's a result for request.files.get("someName") doesn't mean a file was actually uploaded. You should check that the filename exists, too, in order to validate if a file was indeed uploaded.
Take for example, the following HTML
<form action="/form_endpoint" method="POST">
<input type="text" name="data">
<input type="submit" value="submit">
</form>
You would access the value the user input in the data field by data = request.form.get("data")

Issues sending and receiving a GET request using Flask

I'm having issues with correctly sending and receiving a variable with a GET request. I cannot find any information online either. From the HTML form below, you can see I'm sending the value of 'question' but I'm also receiving 'topic' from a radio button in the form (though the code is for that is not below).
I want to send 'topic' using POST but use GET for 'question'. I'm aware that the form method is POST though I'm not sure how to cater for both POST and GET.
HTML Form:
<form method="POST" action="{{ url_for('topic', question=1) }}">
My second issue is that I'm unsure how to receive 'topic' AND 'question' from the form. I've managed to receive 'topic' as seen below but I'm not quite sure how to receive 'question'. Preferably it would be better for the URL to be like so:
www.website.com/topic/SomeTopic?question=1
For the code below, I found online that request.args[] is used for receiving GET requests though I'm not sure if it is correct.
Flask:
#app.route('/topic/<topic>', methods=['POST', 'GET'])
def questions(topic):
question = request.args['questions']
return render_template('page.html')
The question is
How do I send two variables from a form using GET and POST for different variables at the same time.
How would I go about receiving both variables?
The short answer to your question is that you can't send both GET and POST using the same form.
But if you want your url to look like you specified:
www.website.com/topic/SomeTopic?question=1
then you're almost there. First you will need to already know the name of the topic as you have to specify that in your call to url_for() for the questions url.
<form method="GET" action="{{ url_for('questions', topic_name="cars") }}">
# Your url will be generated as www.website.com/topic/cars
flask
# Note that I changed the variable name here so you can see how
# its related to what's passed into url_for
#app.route('/topic/<topic_name>')
def questions(topic_name):
question = request.args['question']
return render_template('page.html')
Now when you submit your form, your input will be sent as a GET, an asumming you have an input field with the name question you'll be able to get the value of that field.

What is the cause of the Bad Request Error when submitting form in Flask application?

After reading many similar sounding problems and the relevant Flask docs, I cannot seem to figure out what is generating the following error upon submitting a form:
400 Bad Request
The browser (or proxy) sent a request that this server could not understand.
While the form always displays properly, the bad request happens when I submit an HTML form that ties to either of these functions:
#app.route('/app/business', methods=['GET', 'POST'])
def apply_business():
if request.method == 'POST':
new_account = Business(name=request.form['name_field'], email=request.form['email_field'], account_type="business",
q1=request.form['q1_field'], q2=request.form['q2_field'], q3=request.form['q3_field'], q4=request.form['q4_field'],
q5=request.form['q5_field'], q6=request.form['q6_field'], q7=request.form['q7_field'],
account_status="pending", time=datetime.datetime.utcnow())
db.session.add(new_account)
db.session.commit()
session['name'] = request.form['name_field']
return redirect(url_for('success'))
return render_template('application.html', accounttype="business")
#app.route('/app/student', methods=['GET', 'POST'])
def apply_student():
if request.method == 'POST':
new_account = Student(name=request.form['name_field'], email=request.form['email_field'], account_type="student",
q1=request.form['q1_field'], q2=request.form['q2_field'], q3=request.form['q3_field'], q4=request.form['q4_field'],
q5=request.form['q5_field'], q6=request.form['q6_field'], q7=request.form['q7_field'], q8=request.form['q8_field'],
q9=request.form['q9_field'], q10=request.form['q10_field'],
account_status="pending", time=datetime.datetime.utcnow())
db.session.add(new_account)
db.session.commit()
session['name'] = request.form['name_field']
return redirect(url_for('success'))
return render_template('application.html', accounttype="student")
The relevant part of HTML is
<html>
<head>
<title>apply</title>
</head>
<body>
{% if accounttype=="business" %}
<form action="{{ url_for('apply_business') }}" method=post class="application_form">
{% elif accounttype=="student" %}
<form action="{{ url_for('apply_student') }}" method=post class="application_form">
{% endif %}
<p>Full Name:</p>
<input name="name_field" placeholder="First and Last">
<p>Email Address:</p>
<input name="email_field" placeholder="your#email.com">
...
The problem for most people was not calling GET or POST, but I am doing just that in both functions, and I double checked to make sure I imported everything necessary, such as from flask import request. I also queried the database and confirmed that the additions from the form weren't added.
In the Flask app, I was requesting form fields that were labeled slightly different in the HTML form. Keeping the names consistent is a must. More can be read at this question Form sending error, Flask
The solution was simple and uncovered in the comments. As addressed in this question, Form sending error, Flask, and pointed out by Sean Vieira,
...the issue is that Flask raises an HTTP error when it fails to find a
key in the args and form dictionaries. What Flask assumes by default
is that if you are asking for a particular key and it's not there then
something got left out of the request and the entire request is
invalid.
In other words, if only one form element that you request in Python cannot be found in HTML, then the POST request is not valid and the error appears, in my case without any irregularities in the traceback. For me, it was a lack of consistency with spelling: in the HTML, I labeled various form inputs
<input name="question1_field" placeholder="question one">
while in Python, when there was a POST called, I grab a nonexistent form with
request.form['question1']
whereas, to be consistent with my HTML form names, it needed to be
request.form['question1_field']

Categories