How to write python script in flask - python

I have problem about my python script with HTML.
I'm newbie.
My python script looks as follow:
#!/usr/bin/python3.4
# Import modules for CGI handling
import cgi, cgitb
# Create instance of FieldStorage
form = cgi.FieldStorage()
# Get data from fields
first_name = form.getvalue('first_name')
last_name = form.getvalue('last_name')
print("Content-type:text/html\r\n\r\n")
print("<html>")
print("<head>")
print("<title>Hello - Second CGI Program</title>")
print("</head>")
print("<body>")
print("<h2>Hello %s %s</h2>" % (first_name, last_name))
print("</body>")
print("</html>")
and my HTML file:
<form action="hello_get.py" method="get">
First Name: <input type="text" name="first_name"> <br />
Last Name: <input type="text" name="last_name" />
<input type="submit" value="Submit" />
</form>
I run HTML and write to input first name and last name, but my script doesn't start. It's just show the windows If I want to open script, or save it.
EDIT:
My HTML:
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
<p>Want to get in touch with me? Fill out the form below to send me a message and I will try to get back to you within 24 hours!</p>
<!-- Contact Form - Enter your email address on line 19 of the mail/contact_me.php file to make this form work. -->
<!-- WARNING: Some web hosts do not allow emails to be sent through forms to common mail hosts like Gmail or Yahoo. It's recommended that you use a private domain email address! -->
<!-- NOTE: To use the contact form, your site must be on a live web host with PHP! The form will not work locally! -->
<form action="/app/get.cgi" method="get">
<div class="row control-group">
<div class="form-group col-xs-12 floating-label-form-group controls">
<label>Name</label>
<input type="text" name="name" class="form-control" placeholder="Name" id="name" required data-validation-required-message="Please enter your name.">
<p class="help-block text-danger"></p>
</div>
</div>
<div class="row control-group">
<div class="form-group col-xs-12 floating-label-form-group controls">
<label>Email Address</label>
<input type="email" name="email" class="form-control" placeholder="Email Address" id="email" required data-validation-required-message="Please enter your email address.">
<p class="help-block text-danger"></p>
</div>
</div>
<div class="row control-group">
<div class="form-group col-xs-12 floating-label-form-group controls">
<label>Message</label>
<textarea rows="5" name="message" class="form-control" placeholder="Message" id="message" required data-validation-required-message="Please enter a message."></textarea>
<p class="help-block text-danger"></p>
</div>
</div>
<br>
<div id="success"></div>
<div class="row">
<div class="form-group col-xs-12">
<button type="submit" class="btn btn-default">OdoslaƄ</button>
</div>
</div>
</form>
</div>
</div>
</div>
(my python script) get.cgi:
#!/usr/bin/python3.4
# Import modules for CGI handling
import cgi, cgitb
file = open('file.txt', mode='w')
form = cgi.FieldStorage()
name = form.getvalue('name')
email = form.getvalue('email')
message = form.getvalue('message')
file.write(name)
file.write(email)
file.write(message)
file.close()
and my app.py which is main flask module
from flask import Flask, render_template, request
app = Flask(__name__)
app.secret_key = 'mypa$$w0rd'
#app.route('/')
#app.route('/index.html')
def index():
return render_template('index.html')
#app.route('/about.html')
def about():
return render_template('about.html')
#app.route('/contact.html')
def contact():
return render_template('contact.html')
#app.route('/post.html')
def sample_post():
return render_template('post.html')
if __name__ == '__main__':
app.run()
I'm running it as localhost.
Output when i click on SEND(in my html it equals ODOSLAT in my language):
Not Found
The requested URL was not found on the server. If you entered the URL
manually please check your spelling and try again.
And text field in browser search now looks like this:
http://127.0.0.1:5000/app/get.cgi?name=asdf&email=julo.marko%40gmail.com&message=asfasfasf

If you have a Flask web application, you don't need any .cgi scripts. Just point your form to the appropriate route in flask. With the url in your html:
#app.route('/api/get.cgi')
def api_get():
first_name = request.args.get('first_name')
last_name = request.args.get('last_name')
return """<html><body><h2>Hello %s %s</h2></body></html>""" % (first_name, last_name)

Related

POST request to Flask Blueprint api not working

I am trying to execute a form POST request. The request is received at the route api function but the POST condition is not executing.
Code
<form class="pt-2 pb-4" action = "{{ url_for('data_sources_api.testfn') }}" method = "POST">
<div class="row">
<div class="col-md-4 mb-3">
<label for="url" class="form-label">URL</label>
<input type="text" class="form-control" id="url" name="url" aria-describedby="emailHeurllp"
placeholder="Enter new events top domain source url">
</div>
<div class="col-md-4 mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Enter Organization Name">
</div>
<div class="col-md-12">
<button type="button" class="btn btn-secondary mr-2" value="submit" name = "submit">Submit</button>
</div>
</div>
</form>
Flask Code
#data_sources_api.route('/login/test', methods=["GET", "POST"])
def testfn():
# Check if user is loggedin
if loggedin():
# User is loggedin, render the home page
if request.method == 'POST':
print("POST Request Received")
result = request.form
return render_template('users/data-sources.html', role=session['role'])
return redirect(url_for('account_api.login'))
The request received is GET when i click the submit button and not POST :(
Thanks in advance
I think the problem is with button. Replace the button with input type="submit":
<input type="submit" value="Submit">
Here is the example of Django form.

Update the password if the user has forgotten while Login-in, Python Flask

I am trying to update the password if the user has forgotten while Login-in. But continuously it is giving the same error given below.
Bad Request: The browser (or proxy) sent a request that this server could not understand.
app.py
#app.route('/NewPassword', methods=['POST', 'GET'])
def NewPassword():
if request.method == 'POST':
OldEmail = request.form['NewPswdInputEmail']
OldPhone = request.form['NewPswdInputPhoneNo']
NewPaswd = request.form['NewPaswdInputPassword']
cur = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cur.execute("UPDATE USERS SET Paswd='" + NewPaswd + "' WHERE Email ='" + OldEmail + "' OR Phone ='" + OldPhone + "'")
cur.connection.commit()
return "Password Updated"
return render_template('NewPassword.html')
NewPassword.html
<form action="/NewPassword" method="post" oninput='NewPaswdConPassword.setCustomValidity(NewPaswdConPassword.value != NewPaswdInputPassword.value ? "Password does not match." : "")'>
<div class="form-group">
<label for="customRadio">Select Option to Change Password Between Email & Phone No.</label>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="customRadioInline1" name="customRadioInline" value="Email" class="custom-control-input" checked>
<label class="custom-control-label" for="customRadioInline1">Email Id</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="customRadioInline2" name="customRadioInline" value="Phone" class="custom-control-input">
<label class="custom-control-label" for="customRadioInline2">Phone No.</label>
</div>
</div>
<div class="form-group" id="EmailShowHide">
<label for="NewPswdInputEmail">Email Address</label>
<input type="email" class="form-control" name="loginInputEmail" id="NewPswdInputEmail" aria-describedby="emailHelp" placeholder="Email address">
<small id="loginemailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="form-group" id="PhoneShowHide" style="display: none">
<label for="NewPswdInputPhoneNo">Phone Number</label>
<input type="tel" id="NewPswdInputPhoneNo" name="NewPswdInputPhoneNo" class="form-control" pattern="[0-9]{4}[0-9]{2}[0-9]{4}" placeholder="Phone number">
<small id="NewPswdPhoneHelpInline" class="text-muted">Enter Valid Number</small>
</div>
<div class="form-group">
<div class="tool">
<label for="NewPaswdInputPassword">New Password</label>
<div class="input-group" id="NewPaswdShowHide">
<input type="password" class="form-control" name="NewPaswdInputPassword" id="NewPaswdInputPassword" pattern="^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9]).{8,20}$" placeholder="New password" required>
<div class="input-group-append">
<a class="btn btn-primary">
<i class="bi bi-eye-slash" aria-hidden="true"></i>
</a>
</div>
</div>
<span class="tooltext">Password Must be Alphanumeric with atleast an UpperCase & LowerCase Characters</span>
<small id="NewPaswdHelpInline" class="text-muted">Must be 8-20 characters long.</small>
</div>
</div>
<div class="form-group">
<label for="NewPaswdInputConPassword">Confirm New Password</label>
<input type="password" class="form-control" name="NewPaswdConPassword" id="NewPaswdInputConPassword" placeholder="Confirm new password" required>
</div>
<button type="submit" name="Login" id="NewPaswdSubmit" class="btn btn-primary">Submit</button>
</form>
I am trying to do is, if my database "USERS" has Email or Phone no. then Paswd will get updated with the new password which is input by the user
Please tell me what I am doing wrong.
I assume you are using Flask. Is your application running in debug mode?
Running the application in debug mode can help identify where the issue is.
The issue is with the email HTML form input. When you submit a form, the data is sent as key=value pairs, in this case you are using Flask so it is a python dictionary. So in the /NewPassword route, when you request request.form['NewPswdInputEmail'], you are grabbing a value in that dictionary submitted from the form with 'NewPswdInputEmail' as a key.
In the form input the key is the name attribute.
That's why you get the KeyError because the name in the email input form has name="loginInputEmail" instead of name="NewPswdInputEmail"
All you need to do is rename loginInputEmail attribute in the email input field to NewPswdInputEmail.

405 Method Not Allowed Error in post request while creating user

I'm making a user registration form in which I have made a post request to get the user input data in a print out form but 405 Method Not allowed error causing the problem. I'm a newbie so that's why I couldn't figure out what's going wrong.
CONTROLLER CLASS:
import web
from Models import RegisterModel
urls = (
"/", "Home",
"/register", "Register",
"/post", "PostRegistration",
)
render = web.template.render("Views/Templates", base="MainLayout")
app = web.application(urls, globals())
# Classes/routes
class Home:
def GET(self):
return render.Home()
class Register:
def GET(self):
return render.Register()
class PostRegistration:
def POST(self):
data = web.input()
reg_model = RegisterModel.RegisterModelCls()
reg_model.insert_user(data)
return data.username
if __name__ == "__main__":
app.run()
Registration form:
<div class="container">
<h2>Register Account</h2>
<br /><br />
<form>
<div class="form-group label-static is-empty">
<label for="username" class="control-label">Username</label>
<input id="username" name="username" class="form-control"
type="text" placeholder="Choose a username" />
</div>
<div class="form-group label-static is-empty">
<label for="display_name" class="control-label">Full Name</label>
<input id="display_name" name="name" class="form-control"
type="text" placeholder="Enter your full name" />
</div>
<div class="form-group label-static is-empty">
<label for="email" class="control-label">Email Address</label>
<input id="email" name="email" class="form-control" type="email"
placeholder="Enter your Email" />
</div>
<div class="form-group label-static is-empty">
<label for="password" class="control-label">Password</label>
<input id="password" name="password" class="form-control"
type="password" placeholder="Make a password" />
</div>
<a type="submit" href="/post" class="btn btn-info waves-effect"
>Submit <div class="ripple-container"></div></a>
</form>
</div>
RegistrationModel.py class (which suppose to print the user input)
import pymongo
from pymongo import MongoClient
class RegisterModelCls:
def insert_user(self, data):
print("data is: " + data)
Error:
http://0.0.0.0:8080/
127.0.0.1:64395 - - [06/Sep/2019 00:19:16] "HTTP/1.1 GET /post" - 405
Method Not Allowed
You're mixing GET and POST.
The Error indicates you're doing a "GET" operation, on the url '/post'.
web.py takes the URL and looks it up in the urls list, and identifies the url '/post' is handled by the class "PostRegistration".
So, web.py calls the GET method on class PostRegistration, which doesn't exist, or, as web.py says "Method Not Allowed".
To get past that, either use a POST operation (as #Barmar suggests) or, rename PostRegistration.POST(self) to PostRegistration.GET(self).

How do you run a python script using html button (flask)

I am trying to run a python script using html button in flask. I want it so that when the users press the button in html, the script which sends email in python will run.
This is the HTML portion. I want the python script to run when the user press the submit button.
<div class="container">
<h1 class="brand"><span>Haze</span> Alertion</h1>
<div class="wrapper">
<div class="company-info">
<h3>Haze Warning Signup</h3>
<ul>
<li><i class="fa fa-road"></i> Polytechnic</li>
<li><i class="fa fa-phone"></i> 1234-5678</li>
<li><i class="fa fa-envelope"></i> smartlifestyle#hotmail.com</li>
</ul>
</div>
<div class="contact">
<h3>Registration</h3>
<div class="alert">Your message has been sent</div>
<form id="contactForm">
<p>
<label>Name</label>
<input type="text" name="name" id="name" required>
</p>
<p>
<label>Location</label>
<input type="text" name="company" id="company">
</p>
<p>
<label>Email Address</label>
<input type="email" name="email" id="email" required>
</p>
<p>
<label>Repeat Email Address</label>
<input type="email" name="phone" id="phone">
</p>
<p class="full">
<label>Any Special Instructions</label>
<textarea name="message" rows="5" id="message"></textarea>
</p>
<p class="full">
<button type="submit">Submit</button>
</p>
</form>
</div>
</div>
And this is the python script.
import smtplib
import config
import data
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/Email_Signup')
def Email_signup():
return render_template('Email_Signup(PSI).html')
def send_email(subject, msg):
try:
server = smtplib.SMTP('smtp.gmail.com:587')
server.ehlo()
server.starttls()
server.login(config.EMAIL_ADDRESS, config.PASSWORD)
message = 'Subject: {}\n\n{}'.format(subject, msg)
server.sendmail(config.EMAIL_ADDRESS, data.EMAIL_ADDRESS, message)
server.quit()
print("Success: Email sent!")
except:
print("Email failed to send.")
subject = "Haze Warning"
msg = "Brave yourselves, Haze is coming!"
send_email(subject, msg)
Please take a look at this docs
You can't just place button without any form.
Or you have to place simple link like:
Email Signup
You should access the route with javascript.
Checkout AJAX with jQuery:
http://flask.pocoo.org/docs/0.12/patterns/jquery/
Here's a very similar question:
How to make server side code run when a button is cliked?

Python flask form gives 405

I have this form and every time I try to post it to the method in the buttom of the Question. The application just gives me a 405 error directly. I have checked that my database works by using the same method in the console.
(I have removed alot of html because it was just styling and stuff like that)
<form action="/register" method="post" class="grid">
<div class="cell colspan3" style="margin-left:2%;">
<div class="input-control modern text">
<input type="email" name="email" id="email">
<span class="label">Email</span>
<span class="informer">Skriv din email</span>
<span class="placeholder">Email</span>
</div>
</div>
<div class="cell colspan3">
<div class="input-control modern text cell">
<input type="text" name="username" id="username" >
<span class="label">Brugernavn</span>
<span class="informer">Skriv dit brugernavn</span>
<span class="placeholder">Brugernavn</span>
</div>
</div>
<div class="cell colspan3">
<div class="input-control modern text cell">
<input type="password" name="password" id="password">
<span class="label">Password</span>
<span class="informer">Skriv dit password</span>
<span class="placeholder">Password</span>
</div>
</div>
<div class="cell colspan3">
<div class="input-control modern text cell">
<input type="password" name="passwordconfirm" id="passwordconfirm">
<span class="label">Gentag password</span>
<span class="informer">Skriv dit password igen.</span>
<span class="placeholder">Gentag password</span>
</div>
</div>
<div class="cell colspan3">
<label class="input-control checkbox ">
<input type="checkbox" name="accept_tos" id="accept_tos">
<span class="check"></span>
<span class="caption">Jeg accepterer hjemmesidens regler</span>
</label>
</div>
<div class="cell colspan3">
<div class="input-control cell">
<button class="button success" type="submit">Registrer</button>
</div>
</div>
</div>
</div>
</form>
The python method that I call with my html post form:
#app.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm(request.form)
if request.method == 'POST' and form.validate():
newUser = User(form.username.data, form.email.data, form.password.data)
db.session.add(newUser)
db.session.commit()
return render_template('login.html')
else:
return render_template('register.html')
And the RegistrationForm method looks like this:
class RegistrationForm(Form):
username = StringField('username', [validators.Length(min=4, max=25)])
email = StringField('email', [validators.email, validators.Length(min=4, max=40)])
password = PasswordField('password',
[validators.Required(),
validators.EqualTo('confirm', message='Passwords skal matche hinanden.')
])
confirm = PasswordField('passwordconfirm')
accept_tos = BooleanField('Jeg accepterer regler for denne hjemmeside', [validators.Required()])
obviously there'snt any problem in these codes unless you have url_prefix for your current app like :
app = Blueprint('user', __name__, url_prefix='/user/')
and u have another blueprint with url_prefix like :
app = Blueprint('general', __name__, url_prefix='/')
with another funtion like :
#app.route('/register', methods=['GET'])
in the blueprint ...
and your form is posting data to '/register' instead of '/user/register'
If that really is the code you're using, I can't see why you're getting a 405 Unsupported Method rather than a validation error. You need to render the hidden CSRF field in the html form.
<form ...>
{{ form.hidden_tag() }}
There are other things wrong with this code. Redirect to login, don't render the template from the register view. Use form.validate_on_submit(). Don't pass request.form to the form. Let the form render the inputs, don't write the html yourself.
Try changing
if request.method == 'POST' and form.validate():
to
if form.validate_on_submit():

Categories