Method Not Allowed flask error 405 - python

I am developing a flask registration form, and I receive an error:
error 405 method not found.
Code:
import os
# Flask
from flask import Flask, request, session, g, redirect, url_for, abort, \
render_template, flash, Markup, send_from_directory, escape
from werkzeug import secure_filename
from cultura import app
# My app
from include import User
#app.route('/')
def index():
return render_template('hello.html')
#app.route('/registrazione', methods=['POST'])
def registration():
if request.method == 'POST':
username= request.form.username.data
return render_template('registration.html', username=username)
else :
return render_template('registration.html')
registration.html:
<html>
<head> <title>Form di registrazione </title>
</head>
<body>
{{ username }}
<form id='registration' action='/registrazione' method='post'>
<fieldset >
<legend>Registrazione utente</legend>
<input type='hidden' name='submitted' id='submitted' value='1'/>
<label for='name' >Nome: </label>
<input type='text' name='name' id='name' maxlength="50" /> <br>
<label for='email' >Indirizzo mail:</label>
<input type='text' name='email' id='email' maxlength="50" />
<br>
<label for='username' >UserName*:</label>
<input type='text' name='username' id='username' maxlength="50" />
<br>
<label for='password' >Password*:</label>
<input type='password' name='password' id='password' maxlength="50" />
<br>
<input type='submit' name='Submit' value='Submit' />
</fieldset>
</form>
</body>
</html>
when I visit localhost:5000/registrazione, I receive the error. What am I doing wrong?

This is because you only allow POST requests when defining your route.
When you visit /registrazione in your browser, it will do a GET request first. Only once you submit the form your browser will do a POST. So for a self-submitting form like yours, you need to handle both.
Using
#app.route('/registrazione', methods=['GET', 'POST'])
should work.

change name of method registration
#app.route('/registrazione', methods=['POST'])
def registrazione():
if request.method == 'POST':
username= request.form.username.data
return render_template('registration.html', username=username)
else :
return render_template('registration.html')

Just for people reading on it now.
You have to render the /registrazione first, befor you can access the form data. Just write.
#app.route("/registrazione")
def render_registrazione() -> "html":
return render_template("registrazione.html")
before you define def registration(). Sequence is key. You can't access data before the even are available. This is my understanding of the problem.

For the error 500 (internal server error) in
username = request.form.username
write instead
username = request.args.get("username")

Example of a flask app using wsgi with JQuery, Ajax and json:
activecalls.py
from flask import Flask, jsonify
application = Flask(__name__, static_url_path='')
#application.route('/')
def activecalls():
return application.send_static_file('activecalls/active_calls_map.html')
#application.route('/_getData', methods=['GET', 'POST'])
def getData():
#hit the data, package it, put it into json.
#ajax would have to hit this every so often to get latest data.
arr = {}
arr["blah"] = []
arr["blah"].append("stuff");
return jsonify(response=arr)
if __name__ == '__main__':
application.run()
Javascript json, /static/activecalls/active_calls_map.html:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<script>
$.ajax({
//url : "http://dev.consumerunited.com/wsgi/activecalls.py/_getData",
url : "activecalls.py/_getData",
type: "POST",
data : formData,
datatype : "jsonp",
success: function(data, textStatus, jqXHR)
{
//data - response from server
alert("'" + data.response.blah + "'");
},
error: function (jqXHR, textStatus, errorThrown)
{
alert("error: " + errorThrown);
}
});
</script>
When you run this. The alert box prints: "stuff".

I was also getting this error, I was going through all of this documentation and trying to sort this out, but at the end it was a silly mistake.
Below code was generating the 405 Method Not Allowed error
import requests
import json
URL = "http://hostname.com.sa/fetchdata/"
PARAMS = '{ "id":"111", "age":30, "city":"New Heaven"}'
response = requests.post(url = URL, json = PARAMS)
print(response.content)
It was due to an extra / at the end of url, when I removed it, it was gone. The below update on the requesting URL fixed it
URL = "http://hostname.com.sa/fetchdata"

I was stuck over same issue, I am showing my Login page route as default route and when I try to submit with default route then I got the issue because I had configured POST request on login route but not on the default application route and when I had added the 'POST' method configuration for my default route too, everything is working as expected. The configuration I had done is as follows:
#routes.route("/", methods=['GET', 'POST'] )
#routes.route("/admin-login", methods=['GET', 'POST'])
def admin_login():
...
Hope, this would help anyone facing the similar issue.

Related

Trying to pass two parameters from an html form in flask (in url) to then run in a python program

I'm pretty new to this and I have a python algorithm which I want to run with two parameters that I get from an html form. Here is my html code:
<form action="result/">
<p><input class="w3-input w3-padding-16" method = "post" type="text" placeholder="Playlist URI" required name="URI"></p>
<p><input class="w3-input w3-padding-16" method = "post" type="text" placeholder="Spotify Username" required name="Username"></p>
<p>
<button class="w3-button w3-light-grey w3-padding-large" type="submit">
<i class="fa fa-paper-plane"></i> Submit
</button>
</p>
</form>
It redirects me to http://127.0.0.1:5000/result/?URI=b&Username=c, when I input b and c into the form.
I can't figure out how to accept them as parameters though, and it just returns this error:
404 Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
My python code looks like this:
#app.route('/result.html/<URI>&<username>')
def result(URI,username):
return render_template("result.html", uri=URI, username=username)
you can access parameters in get request using request in flask
example:
from flask import Flask, request
app = Flask(__name__)
#app.route("/result.html")
def result():
uri = request.args.get("uri")
username = request.args.get("username")

How to save to a list every input I receive from the same html form?

how can I save to a list every input I receive from the same form?
How would like to save in the list every weight the user input.
Is it possible to save all the weights the user insert? Also if he reloads the page?
This is the form:
<form action="/send" method="POST">
<label for="">Weight</label>
<input type="text" name="weight">
<label for="">Height</label>
<input type="text" name="height">
<input type="submit" value="submit">
<br>
<div class="alert">
{{ BMI }}
</div>
And this is the flask app:
from flask import Flask, render_template, url_for, request
import schedule
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def index():
return render_template('index.html')
#app.route('/send', methods=['GET', 'POST'])
def send():
if request.method=='POST':
weight = request.form['weight']
height = request.form['height']
a = float(weight)
b = float(height)
BMI = a/(b**2)
weights = []
weights.append(weight)
return render_template('index.html', BMI=BMI, weights = weights)
You need something to persist this data between requests. If you only need it for a short period of time, you can just use a session. The docs for Flask-Session appear to show it being imported from flask.ext.session now, but my version is imported as from flask_session import Session.
Below is a minimal but complete toy example to show how this works (in this case I just store BMI but you can store multiple lists in the session dict). Note that, if you use the default session that comes with Flask, its storage capacity is very small; this is why I'm persisting session data to a file.
If you need the data to persist for longer (i.e. permanently) then you'll need to use a database. A point of note: twice people have advocated storing this data in a global variable. This is terrible for a web app because multiple users will start trampling over each others' data, not to mention that multiple processes will start getting out of sync.
from flask import Flask, render_template_string, request, session
from flask_session import Session
app = Flask(__name__)
app.config['SECRET_KEY'] = b'_5#y2L"F4Q8z\n\xec]/'
app.config['SESSION_TYPE'] = 'filesystem'
sess = Session()
sess.init_app(app)
homepage_template = """
<form method="POST" action="{{ url_for('bmi_submission') }}" id="bmi_form">
Weight: <input type="text" name="weight" value=""><br>
Height: <input type="text" name="height" value=""><br>
<input type="submit" value="Submit">
</form>
<div id="result_div"></div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script>
$("#bmi_form").submit(function(e) {
e.preventDefault();
var form = $(this);
var url = form.attr('action');
$.ajax({
type: "POST",
url: url,
data: form.serialize(),
context: form,
success: function(resp) {
$("#result_div").html(resp);
}
});
});
</script>
"""
#app.route('/', methods=['GET'])
def homepage():
return render_template_string(homepage_template)
#app.route('/calc_bmi', methods=['POST'])
def bmi_submission():
weight = request.form.get('weight')
height = request.form.get('height')
a = float(weight)
b = float(height)
BMI = a/(b**2)
if session.get('bmi'):
session['bmi'].append(BMI)
else:
session['bmi'] = [BMI]
return '<br>'.join([str(item) for item in session['bmi']])
if __name__ == '__main__':
app.run()

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

Python Flask : url_for to pass the variable to function from form template

I tried this approach to pass the form input variable to function via url_for method. But its not working. can anyone check and let me know whats wrong in this code.
Function:
#app.route('/report_data/<year>/<week>', methods = ['POST'])
def report_data(year,week):
print year
print woy
HTML Code :
<html>
<body>
<form action="{{ url_for('report_data', year=n_year, week=n_woy) }}" method="post">
<h3> Enter the details </h3>
Year :
<input type="text" name="n_year"> <br>
<br>
Week :
<input type="text" name="n_woy"> <br>
<br>
<input type="submit" value="Submit"> <br>
</form>
</body>
</html>
Issue:
Getting "None" for both variable.
Firstly, How do you provide year, week values before submitting them in your HTML code ?
Did you render the HTML template in your function? If not, how does your flask function knows that you were seeking from that specific form?
If this is your Flask app code -
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/report_data', methods = ['POST', 'GET'])
def report_data():
if request.method == 'POST':
result = request.form
query_year = result['n_year'].encode('ascii', 'ignore')
query_week = result['n_woy'].encode('ascii', 'ignore')
print(query_year, query_week)
return render_template('so_test.html')
if __name__ == '__main__':
app.run(debug=True)
And opened the URL -
http://127.0.0.1:5000/report_data
And I get this picture.
Once I post the data, I can see this data in my Flask app console.
('2018','08')

Getting JSON data in Flask function

I am just learning Flask. I am trying to get a JSON object through a jQuery call into flask. My html look like this,
<html>
<head>
<title>Passenger</title>
<style type="text/css"></style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<div>
<form onsubmit="return false">
<input class="name" type="text" placeholder="Name">
<input class="submit" type="submit" placeholder="Go">
</form>
</div>
<script>
$("input.submit").click(function(e){
$.post( "/save", {name: $("input.name").val(), time: "2pm"});
});
</script>
</body>
</html>
The Flask app file looks like,
from flask import Flask
from flask import redirect, url_for, jsonify
from flask import request
import json
app = Flask(__name__)
#app.route('/')
def home():
return redirect(url_for('static',filename='index.html'))
#app.route('/save', methods=['PUT','POST'])
def get_name():
print request.json
return request.json
if __name__=='__main__':
app.run(debug=True)
Running this code returns None. I am expecting to get back the JSON object [{name: $("input.name").val(), time: "2pm"}]. Thanks.
The problem is that the jquery post is not using the data type of json. You can see that by printing out the request content_type:
print request.content_type
application/x-www-form-urlencoded; charset=UTF-8
Change the Javascript to post json, and request.json should be populated with json as you expect.
var data = JSON.stringify({name: $("input.name").val(), time: "2pm"});
$.ajax("/save", {
data: data,
contentType : "application/json",
type : "POST"
});
Notice that after changing the JS code, request.content_type will be application/json

Categories