HTTP 405 error when trying to POST to Flask app - python

When I try to submit a request from my web form to my flask app I get a HTTP 405 method not allowed.
app.py (Python App code):
# app.py
from flask import Flask, render_template, request, redirect, json, url_for
from flaskext.mysql import MySQL
app = Flask(__name__)
# Database connection info. Note that this is not a secure connection.
app.config['MYSQL_DATABASE_USER'] = 'root'
app.config['MYSQL_DATABASE_PASSWORD'] = ''
app.config['MYSQL_DATABASE_DB'] = 'RamsterDB'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql = MySQL()
mysql.init_app(app)
conn = mysql.connect()
cursor = conn.cursor()
mysql = MySQL()
mysql.init_app(app)
conn = mysql.connect()
cursor = conn.cursor()
#app.route('/')
def main():
return render_template('search.html')
#app.route('/showRegister', methods=['POST','GET'])
def showRegister():
return render_template('register.html')
#app.route('/register', methods=['POST, GET'])
def register():
# read the posted values from the UI
#try:
_username = request.form['inputUsername']
_password = request.form['inputPassword']
# validate the received values
if _username and _password:
return json.dumps({'html': '<span>All fields good !!</span>'})
else:
return json.dumps({'html': '<span>Enter the required fields</span>'})
#return render_template('register.html')
if __name__ == '__main__':
app.debug = True
app.run()
register.html (Registration page code):
<!DOCTYPE html>
<html lang="en">
<head>
<title>Ramster</title>
<link rel="stylesheet" href="/static/index.css">
<script src="/static/js/jquery-1.11.2.js"></script>
<script src="../static/js/register.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, height=100%">
</head>
<body>
<div class="topnav">
Login
Register
</div>
<div class="content">
<h2>Ramster</h2>
<p>Register your team</p>
<form class="example" method="post" action="" style="margin:left;max-width:600px">
<input type="text" name="inputUsername" id="inputUsername" placeholder="Username" required autofocus><br><br><br>
<input type="text" name="inputPassword" id="inputPassword" placeholder="Password" required><br><br><br>
<button id="btnRegister" class="example" type="submit">Register</button>
</form>
<!--<form class="example" method="post" action="" style="margin:left;max-width:600px">
<input type="text" placeholder="Username" name="inputUsername">
<input type="text" placeholder="Password" name="inputPassword">
<button type="submit">Register</button>
</form>
<p></p>-->
</div>
<div class="footer">
<p>Terms and Conditions</p>
</div>
</body>
</html>
register.js:
$(function() {
$('#btnRegister').click(function() {
$.ajax({
url: '/register',
data: $('form').serialize(),
type: 'POST',
success: function(response) {
console.log(response);
},
error: function(error) {
console.log(error);
}
});
});
});
error in browser:
jquery-1.11.2.js:9659 POST http://localhost:5000/register 405 (METHOD NOT ALLOWED)
I have tried changing the form parameters as well as the Python code, but nothing seems to be working. I have not attempted to connect to MySQL yet until I fix the 405 issue. I have tried to find an answer but cannot find one anywhere.

You have list with single element instead of list with 2 elements.
Replace
#app.route('/register', methods=['POST, GET'])
with
#app.route('/register', methods=['POST', 'GET'])

Related

python flask session , login and index not working

I have a python flask app with login module implemented using extension python flask. In my login method.
The Error Message
app.py
# import the Flask class from the flask module
from flask import Flask, render_template, redirect, url_for, request, session
# create the application object
app = Flask(__name__)
app.secret_key = "hello"
# use decorators to link the function to a url
##app.route('/')
#def home():
# return "Hello, World!" # return a string
#app.route('/index', methods=['GET'])
def index():
if session.get ('username'):
return render_template('index.html')
else:
return render_template('login.html') # render a template
# route for handling the login page logic
#app.route('/', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or request.form['password'] != 'admin':
error = 'Invalid Credentials. Please try again.'
else:
session['username'] = True
return redirect(url_for('index'))
return render_template('login.html', error=error)
# start the server with the 'run()' method
if __name__ == '__main__':
app.run(debug=True)
login page
login.html
<html>
<head>
<title>Flask Intro - login page</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="container">
<h1>Please login</h1>
<br>
<form action="" method="post">
<input type="text" placeholder="Username" name="username" value="{{
request.form.username }}">
<input type="password" placeholder="Password" name="password" value="{{
request.form.password }}">
<input class="btn btn-default" type="submit" value="Login">
</form>
{% if error %}
<p class="error"><strong>Error:</strong> {{ error }}</p>
{% endif %}
</div>
</body>
</html>
index.html
<DOCTYPE Html>
<html>
<head>
<tile>Addressing a Site</tile>
</head>
<body>
<address>welcome.</address>
</body>
</html>
i am trying to create a session between login and index page,just getting started with python flask framework, login session not working well.
It seems like you are actually having an issue with the methods rather than the session not working.
The Method Not Allowed error means that you are sending a GET/POST request to a page that does not accept that type of request.
Try changing the start of your login form to this
<form action="{{ url_for('login') }}" method="POST">
I just got it running on my computer and this works, the reason it did not work before was because the form was sending the post request to the /index route, which only accepts GET request.
Also, I noticed something else you may want to change.
You currently have this on your index route
if session.get ('username'):
return render_template('index.html')
else:
return render_template('login.html')
But it would be better to change that to this
if session.get ('username'):
return render_template('index.html')
else:
return redirect(url_for('login'))
That way the user is sent back to the login page rather than just being shown the login template from the index page.
I hope all of that helps.

Browser back button takes user back inside after Logout

I have been working on a web interface using Flask and having some issues with back button in browser as after logging out hitting it takes user back inside. I have found similar questions and tried their answers but the issue is not resolved. I am attaching a simple example kindly have a look at it.
Main
from flask import Flask, request,session, redirect, url_for, render_template
from os import urandom
app = Flask(__name__)
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
app.secret_key = urandom(24)
#app.route('/', methods=['POST', 'GET'])
def index():
if request.method == 'POST':
session['Email id'] = request.form.get('Email Id')
Pass = request.form.get('Password')
try:
if session['Email id'] == 'KK#gmail.com' and Pass == 'KKK':
return render_template('Logged_in.html')
except:
return render_template('login.html')
return render_template('login.html')
#app.route('/sign_out')
def sign_out():
session.pop('Email id')
return redirect(url_for('index'))
#app.after_request
def add_header(r):
r.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
r.headers["Pragma"] = "no-cache"
r.headers["Expires"] = "0"
r.headers['Cache-Control'] = 'public, max-age=0'
return r
if __name__ == '__main__':
app.run(host="0.0.0.0", debug=True, threaded=True)
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="{{ url_for('index') }}" method="POST" id="login" class="input-group">
<input type="text" class="input-field" placeholder="Email Id" required name="Email Id">
<input type="text" class="input-field" placeholder="Password" required name="Password">
<button type="submit" class="submit-btn" style="color: white;">Log in</button>
</form>
</body>
</html>
Logged_in.html
<h2>You are Logged in</h2>
<i class="fas fa-sign-out-alt"></i>Log out
Your problem is that when users push the back button their browser will re-do the POST request. You need to use the POST/redirect/GET pattern to prevent this. For this you need four endpoints in totalt:
GET / : Check in the session that the user is logged in and render Logged_in.html, otherwise redirect to /login.html
GET /login.html : Render login.html
POST /sign_in : Check username and password. If successful, update the session and redirect to /
POST /sign_out : Log out the user session and redirect to /login.html
Do not render templates in your POST endpoints, just make them manipulate the session and then redirect.

Form request flask error when trying to submit

i am a beginner programmer in flask and i encounter a problem i rly don't see the problem with my code.
In the login file i have a form and it will send a req to /check but i get an err like: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
I also have the register file with the action route '/' and this works.
Here is the code:
from flask import Flask, render_template, request, url_for, redirect
from models.Data_Base import DataBase
app = Flask(__name__)
db = DataBase()
#app.route('/')
def main_page_render():
return render_template('home.html')
#app.route('/login')
def login_page_render():
return render_template('login.html')
#app.route('/check')
def check_page_render():
print('{} {}'.format(request.form['user_name'], request.form['password']))
if request.form['user_name'] == 'admin' and request.form['password']:
return redirect(url_for('admin_page_render'))
elif db.verify_login(request.form['user_name'], request.form['password']) == True:
return redirect('/fighter/{}'.format(request.form['user_name']))
#app.route('/admin')
def admin_page_render():
return 'Admin Page'
#app.route('/fighter/<username>')
def fighter_page_render(username):
return 'Fighter page'
#app.route('/register')
def register_page_render():
return render_template('register.html')
if __name__ == '__main__':
app.run()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login_page</title>
</head>
<body>
<h2>Login Page</h2>
<form action="/check">
<label for="user_name">User name:</label><br>
<input type="text" id="user_name" name="user_name"><br>
<label for="password">Password:</label><br>
<input type="password" id="password" name="password"><br><br>
<input type="submit" value="Submit">
</form>
<p>Click submit in order to get to your account</p>
</body>
</html>
A Solution can be this, try to do these changes.
app.py
...
#app.route('/check', methods=["GET", "POST"])
def check_page_render():
print('{} {}'.format(request.form['user_name'], request.form['password']))
if request.form['user_name'] == 'admin' and request.form['password']:
return redirect(url_for('admin_page_render'))
elif db.verify_login(request.form['user_name'], request.form['password']) == True:
return redirect('/fighter/{}'.format(request.form['user_name']))
...
/templates/home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login_page</title>
</head>
<body>
<h2>Login Page</h2>
<form action="/check" method="POST">
<label for="user_name">User name:</label><br>
<input type="text" id="user_name" name="user_name"><br>
<label for="password">Password:</label><br>
<input type="password" id="password" name="password"><br><br>
<input type="submit" value="Submit">
</form>
<p>Click submit in order to get to your account</p>
</body>
</html>

werkzeug.routing.BuildError: Could not build url for endpoint 'profile'. Did you mean 'index' instead?

I'm new to programming and I'm following this tutorial: https://www.youtube.com/watch?v=SUC1aTu092w&ab_channel=edureka%21 | I'm trying to make a login system using flask and MySQLdb and I've run into this problem, I'm so confused. There's nothing wrong with the database, I've checked multiple times. I'm using VS code. Error: werkzeug.routing.BuildError: Could not build url for endpoint 'profile'. Did you mean 'index' instead?
app.py
from flask import Flask, render_template, request, redirect, session, url_for
from flask_mysqldb import MySQL
import MySQLdb
app = Flask(__name__)
app.secret_key = "123456789"
app.config["MYSQL_HOST"] = "localhost"
app.config["MYSQL_USER"] = "root"
app.config["MYSQL_PASSWORD"] = "Root123"
app.config["MYSQL_DB"] = "login"
db = MySQL(app)
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
if 'username' in request.form and 'password' in request.form:
username = request.form['username']
password = request.form['password']
cursor = db.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute("SELECT * FROM logininfo WHERE email= %s AND password= %s", (username,password))
info = cursor.fetchone()
if info is not None:
if info['email'] == username and info['password'] == password:
session['loginsuccess'] = True
return redirect(url_for('/profile'))
else:
return redirect(url_for('index'))
return render_template("login.html")
#app.route('/new')
def new_user():
if request.method == "POST":
if "one" in request.form and "two" in request.form and "three" in request.form:
username = request.form['one']
email = request.form['two']
password = request.form['three']
cur = db.connection.cursor(MySQLdb.cursors.DictCursor)
cur.execute("INSERT INTO login.logininfo(name, password, email)VALUES(%s, %s, %s)", (username, password, email))
db.connection.commit()
return redirect(url_for('index'))
return render_template("register.html")
#app.route('/new/profile')
def profile():
if session['loginsuccess'] == True:
return render_template("profile.html")
if __name__ == '__app__':
app.run(debug=True)
login.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Hello World!</title>
</head>
<body>
<div>
<form action="" method="post">
<label>USERNAME</label><br>
<input name="username" type="email" placeholder="Username"><br><br>
<label>PASSWORD</label><br>
<input name="password" type="password" placeholder="Password"><br><br>
<input type="submit" value="LOGIN"><br><br>
</form>
</div>
<div>
<form action="/new">
<label>New Here?</label>
<input value="Register" type="submit">
</form>
</div>
</body>
</html>
register.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Register</title>
</head>
<body>
<div>
<form method="post">
<label>NAME:</label><br>
<input type="text" name="one" id="name"><br><br>
<label>USERNAME:</label><br>
<input type="email" name="two" id="username"><br><br>
<label>PASSWORD:</label><br>
<input type="password" name="three" id="password"><br><br>
<input type="submit" value="CREATE USER">
</form>
</div>
</body>
</html>
profile.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Profile</title>
</head>
<body>
<form action="/">
<h1>Login Successful</h1>
<label>Welcome to your profile</label>
<button type="submit">LOGOUT</button>
</form>
</body>
</html>
Spacing is critical in python. Each line that starts w/ #app.route should start at the far left. Also I fixed your profile route name.
from flask import Flask, render_template, request, redirect, session, url_for
from flask_mysqldb import MySQL
import MySQLdb
app = Flask(__name__)
app.secret_key = "123456789"
app.config["MYSQL_HOST"] = "localhost"
app.config["MYSQL_USER"] = "root"
app.config["MYSQL_PASSWORD"] = "Root123"
app.config["MYSQL_DB"] = "login"
db = MySQL(app)
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
if 'username' in request.form and 'password' in request.form:
username = request.form['username']
password = request.form['password']
cursor = db.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute("SELECT * FROM logininfo WHERE email= %s AND password= %s", (username,password))
info = cursor.fetchone()
if info is not None:
if info['email'] == username and info['password'] == password:
session['loginsuccess'] = True
return redirect(url_for('profile'))
else:
return redirect(url_for('index'))
return render_template("login.html")
#app.route('/new')
def new_user():
if request.method == "POST":
if "one" in request.form and "two" in request.form and "three" in request.form:
username = request.form['one']
email = request.form['two']
password = request.form['three']
cur = db.connection.cursor(MySQLdb.cursors.DictCursor)
cur.execute("INSERT INTO login.logininfo(name, password, email)VALUES(%s, %s, %s)", (username, password, email))
db.connection.commit()
return redirect(url_for('index'))
return render_template("register.html")
#app.route('/profile')
def profile():
if session['loginsuccess'] == True:
return render_template("profile.html")
if __name__ == '__app__':
app.run(debug=True)
At first, you didn't specify the error, which is very important here. At least what I can see is you have this problem:
if __name__ == '__app__':
app.run(debug=True)
And you have to use:
if __name__ == '__main__':
app.run(debug=True)

Python Bottle how to pass parameter as json

I created an api for openerp using bottle
It works well while access using browser
I don't know how to pass it as json parameters
The Problem is
how can i call using api and pass json parameters like
http://localhost/api?name=admin&password=admin&submit=Submit
Here is my wsgi code app.wsgi
import json
import os
import sys
import bottle
from bottle import get, post, run,request,error,route,template,validate,debug
def login():
import xmlrpclib
username = request.forms.get('name')
pwd = request.forms.get('password')
dbname = 'more'
sock_common = xmlrpclib.ServerProxy ('http://localhost:8069/xmlrpc/common')
uid = sock_common.login(dbname, username, pwd)
if uid:
return json.dumps({'Success' : 'Login Sucessful'])
def index():
return '''
<html>
<head>
<title> Portal</title>
</head>
<body>Welcome To PORTAL
<form method="GET" action="/api/links" enctype="multipart/form-data">
Name:<input name="name" type="text"/><br>
Password:<input name="password" type="password"/><br>
<input type="submit" value="Submit" name="submit">
</form>
</body>
</html>'''
def links():
return '''
<html>
<head>
<title> Portal</title>
</head>
<body>
<a href="/api/advisor">Advisor<br>
</body>
</html>'''
application = bottle.default_app()
application.route('/', method="GET", callback=index)
application.route('/', method="POST",callback=login)
request.forms is used for POST or PUT requests. The form in your code uses GET, not POST, so you should use request.query.getall, which gives you access to "URL arguments".
I don't see anything wrong with the code (except pep8 changes), only problem I see is method of the form and location, see the fixed version below ...
import json
import os
import sys
import bottle
from bottle import get, post, run, validate, request, error, route, template, debug
def login():
import xmlrpclib
username = request.forms.get('name')
pwd = request.forms.get('password')
dbname = 'more'
sock_common = xmlrpclib.ServerProxy ('http://localhost:8069/xmlrpc/common')
uid = sock_common.login(dbname, username, pwd)
if uid:
return json.dumps({'Success': 'Login Sucessful'})
def index():
return '''
<html>
<head>
<title> Portal</title>
</head>
<body>Welcome To PORTAL
<form method="POST" action="/" enctype="multipart/form-data">
Name:<input name="name" type="text"/><br>
Password:<input name="password" type="password"/><br>
<input type="submit" value="Submit" name="submit">
</form>
</body>
</html>'''
def links():
return '''
<html>
<head>
<title> Portal</title>
</head>
<body>
<a href="/api/advisor">Advisor<br>
</body>
</html>'''
application = bottle.default_app()
application.route('/', method="GET", callback=index)
application.route('/', method="POST", callback=login)
application.run()

Categories

Resources