Python flask POST request - python

I develop an app in Python and use flask.
Here is a snippet of code that tries to generate a message by user input and then attach it to my database:
#app.route('/MakeMessage',methods = ['POST', 'GET'])
def MakeMessage():
if request.method == 'POST':
user_id = request.form['user_id']
content = request.form['content']
paticipants = [request.form['participant1'],request.form['participant2'],request.form['participant3']]
m = Message(user_id=user_id,content=content,participants=paticipants)
return redirect('/AddMessage',m = m)
#app.route('/AddMessage',methods = ['POST', 'GET'])
def AddMessage(m):
if request.method == 'POST':
db.session.add(m)
db.session.commit()
return 'Your message has been successfully saved'
I know something is wrong with the code, but I don't know what.
Any idea?

AddMessage
takes a parameter m
So in the app.route it should be changed to this
#app.route('/AddMessage/<m>')

You would want to use url_for() in the redirect function to redirect to a route in your application. In addition, you need to put <m> in your route for AddMessage.
from flask import redirect, url_for, request
#app.route('/MakeMessage',methods = ['POST', 'GET'])
def MakeMessage():
if request.method == 'POST':
...
return redirect(url_for('/AddMessage',m=m))
#app.route('/AddMessage/<m>',methods = ['POST', 'GET'])
def AddMessage(m):
...

Related

Local variable 'a_no' referenced before assignment

Can anyone please explain me why I am not able to access a_no in route("/otp")?
Flask code:
from flask import Flask, request, render_template,url_for,redirect
parties=["A","B","C","D"]
app = Flask(__name__)
#app.route('/')
def my_form():
return render_template('home.html')
#return render_template('admin.html')
##################################################################
#app.route('/', methods=['GET','POST'])
def my_form_post():
if request.method == "POST":
adhar_no = request.form['aadhar_num']
return redirect(url_for('verification',adhar_no=adhar_no))
#app.route('/otp',methods = ['POST','GET'])
def verification():
if request.method =="GET":
a_no=request.args.get('adhar_no')
return render_template("otp.html")
if request.method == "POST":
otp_text = request.form['otp']
return a_no
I am getting local variable a_no referenced before assignment. Can anyone help me to solve this error in route /otp?
In your /otp route a_no is initialized explicitly on request.method =="GET" , This initialization will execute only when you browse /otp route with GET request.
While doing POST a_no is uninitialized and still being returned from the route hence the error local variable 'a_no' referenced before assignment.
#app.route('/otp',methods = ['POST','GET'])
def verification():
a_no = '' #initialize a_no here
if request.method == "GET":
a_no = request.args.get('adhar_no')
return render_template("otp.html")
if request.method == "POST":
otp_text = request.form['otp']
return a_no
I still don't understand why you are returning a_no, If you are trying to maintain the state between request for the same client, consider using session

Authentication in Flask application using dictionary database structure

I am creating a basic application to demonstrate the register and login activities in Flask using sessions. For the below code, each user available in the dictionary should be able to login. However, the application only accepts the login for the first user named 'Mary'. I don't understand where did it went wrong.
from flask import Flask, app, session, render_template, request,redirect, url_for, jsonify
app = Flask(__name__)
app.config['SECRET_KEY'] = "Zd9TUg1aE03bHc28"
#app.route('/')
def load():
return render_template("authusers.html")
class Mydatabase:
appdb=[{'username':'Mary','password':'Password#123'},
{'username':'John','password':'Password#456'},
{'username':'Tara','password':'Password#789'}]
mydbusers=Mydatabase()
#app.route('/login',methods = ['GET','POST'])
def success():
if request.method == "POST":
username_val = request.form['user_id']
userpassword_val = request.form['user_password']
for authuser in Mydatabase.appdb:
for authpassword in authuser.values():
if authuser['username'] == username_val and authpassword['password'] == userpassword_val:
session['reg_user'] = username_val
return f'{session.get("reg_user")} have successfully logged into the application';
else:
return redirect(url_for('register'))
#app.route('/logout', methods=['GET','POST'])
def logout():
if 'reg_user' in session:
session.pop('reg_user',None)
return render_template("authusers.html")
#app.route('/register', methods=['GET','POST'])
def register():
return render_template('register.html')
#app.route('/reg_success',methods=['GET','POST'])
def reg_success():
newusercred={'username':request.form['user_id'], 'password':request.form['user_password']}
mydbusers.appdb.append(newusercred)
# return jsonify(Mydatabase.appdb)
return render_template("authusers.html")
if __name__=="__main__":
app.run(debug=True)
I see some logical issue in your code
Try like this ->
class Mydatabase:
appdb=[{'username':'Mary','password':'Password#123'},
{'username':'John','password':'Password#456'},
{'username':'Tara','password':'Password#789'}]
username_val = 'Tara'
userpassword_val = 'Password#789'
d = [a for a in Mydatabase.appdb if a["username"] == username_val and a["password"]==userpassword_val]
if d:
print(f'have successfully logged into the application')
else:
print(f'Wrong credentials')
There are some unwanted loops in your code, and you do return even in the else of part.

werkzeug.routing.BuildError: Could not build url for endpoint 'login' with values ['next']. Did you mean 'core.login' instead?

url_for points to a valid view still getting the below error. I have tried adding the else block to mitigate the error as well but somehow same error is reported.
werkzeug.routing.BuildError: Could not build url for endpoint 'login'
with values ['next']. Did you mean 'core.login' instead?
The code:
from ..extensions import ldap
from .forms import LoginForm
core = Blueprint('core', __name__)
#core.route('/')
#ldap.login_required
def index():
return render_template('index.html')
#core.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
if g.user:
return redirect(url_for('index'))
if request.method == 'POST':
user = request.form['user']
passwd = request.form['passwd']
test = ldap.bind_user(user, passwd)
if test is None or passwd == '':
return 'Invalid credentials'
else:
session['user_id'] = request.form['user']
return redirect('/')
return render_template('sign-in.html', form=form)
#core.route('/logout')
def logout():
session.pop('user_id', None)
return redirect(url_for('index'))
I am using python 3.8 and flask 2.0.2.
This is expected behavior since your login endpoint is part of your core blueprint. When using url_for you should use route endpoint name rather than view function name:
url_for('core.login')
As the exception suggests.
If you need to customize what the endpoint is called you can do it like so:
#core.route('/login', methods=['GET', 'POST'], endpoint='my_login')
...
url_for('core.my_login')
And if there's any confusion you can always inspect app.url_map to see what routes are defined and what are their endpoint names.

Flask: request.referrer returns none when referred from external URL

New to Flask and Python. I've cloned a github Flask chat app example and am trying to get a referrer URL (i.e. the URL the user was in before going into my app). However, when I run the app locally, the referrer link always come back as None if the request comes from an external URL. If it is sent from within the app, I am getting the right referrer URL.
Here's the relevant bits of code. I've tried looking at previous questions, but couldn't find a solution.
My routing logic:
from flask import session, redirect, url_for, render_template, request
from . import main
from .forms import LoginForm
#main.before_request
def before_request():
print("Ref1:", request.referrer)
print("Ref2:", request.values.get("url"))
#main.route('/', methods=['GET', 'POST'])
def index():
form = LoginForm()
ip_address = request.access_route[0] or request.remote_addr
print("ip_addr:", ip_address)
if form.validate_on_submit():
session['name'] = form.name.data
session['room'] = form.room.data
return redirect(url_for('.chat'))
elif request.method == 'GET':
form.name.data = session.get('name', '')
form.room.data = session.get('room', '')
return render_template('index.html', form=form)
#main.route('/chat')
def chat():
name = session.get('name', '')
room = session.get('room', '')
if name == '' or room == '':
return redirect(url_for('.index'))
return render_template('chat.html', name=name, room=room)
My main app code is:
#!/bin/env python
from app import create_app, socketio
app = create_app(debug=True)
if __name__ == '__main__':
socketio.run(app)
Would really appreciate any advice.
Thanks!

How to integrate login required decorator to flask routes with a static user ID and password?

I am new to flask and python, i am trying to add login required and all routes other than home page. I read about flask-login module, haven't had any success. Looking for suggestions !
I tried using flask-login and prevent access of "/data" route. It did not work. My login requirement is very simple, allow login if user pass is admin/admin. And make sure the user is logged in for all subsequent routes.
Here is my flask code
from flask import Flask, render_template, redirect, url_for, request
import subprocess
import os
import datetime
import time
app = Flask(__name__)
#app.route("/")
def home():
now = datetime.datetime.now()
timeString = now.strftime("%Y-%m-%d %H:%M")
templateData = {
'title' : 'HELLO!',
'time': timeString
}
return render_template('main.html', **templateData)
#app.route('/login', 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:
return redirect(url_for('data'))
return render_template('login.html', error=error)
#app.route("/data")
def data():
now = datetime.datetime.now()
timeString = now.strftime("%Y-%m-%d %H:%M")
templateData = {
'title' : 'HELLO!',
'time': timeString
}
return render_template('api.html', **templateData)
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
I dont want /data route to be accessed without login as admin/admin
flask_login should do the trick.
import and use the '#login_required' decorator on any route that you want to make unavailable to users who aren't currently logged in.
from flask_login import login_required
#app.route("/data")
#login_required
def data():
...
...
leave the decorator off of any routes that don't require login.
since you only have need for generic authentication you might look into session login.
for this, you'll need a secret key...
import secrets
app = Flask(__name__)
app.config['SECRET_KEY'] = secrets.token_hex(16)
and an example usage of flask session management.
from flask import session
#app.route('/login', 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['logged_in'] = True
return redirect(url_for('data'))
return render_template('login.html', error=error)

Categories

Resources