Flask
Flask
Advertisements
Previous Page
Next Page
1 GET
2 HEAD
3 POST
Used to send HTML form data to server. Data received by POST method
is not cached by server.
4 PUT
5 DELETE
In order to demonstrate the use of POST method in URL routing, first let
us create an HTML form and use the POST method to send form data to
a URL.
<html>
<body>
<p>Enter Name:</p>
</form>
</body>
</html>
app = Flask(__name__)
@app.route('/success/<name>')
def success(name):
def login():
if request.method == 'POST':
user = request.form['nm']
return redirect(url_for('success',name = user))
else:
user = request.args.get('nm')
if __name__ == '__main__':
app.run(debug = True)
Previous Page
Next Page
app = Flask(__name__)
@app.route('/')
def index():
if __name__ == '__main__':
app.run(debug = True)
app = Flask(__name__)
@app.route('/')
def index():
return render_template(‘hello.html’)
if __name__ == '__main__':
app.run(debug = True)
Flask will try to find the HTML file in the templates folder, in the same
folder in which this script is present.
Application folder
o Hello.py
o templates
hello.html
<!doctype html>
<html>
<body>
</body>
</html>
app = Flask(__name__)
@app.route('/hello/<user>')
def hello_name(user):
if __name__ == '__main__':
app.run(debug = True)
As the development server starts running, open the browser and enter
URL as − http://localhost:5000/hello/mvl
The Jinga2 template engine uses the following delimiters for escaping
from HTML.
{% ... %} for Statements
app = Flask(__name__)
@app.route('/hello/<int:score>')
def hello_name(score):
if __name__ == '__main__':
app.run(debug = True)
<!doctype html>
<html>
<body>
{% if marks>50 %}
{% else %}
{% endif %}
</body>
</html>
Note that the conditional statements if-else and endif are enclosed in
delimiter {%..%}.
The Python loop constructs can also be employed inside the template. In
the following script, the result() function sends a dictionary object to
template results.html when URL http://localhost:5000/result is
opened in the browser.
The Template part of result.html employs a for loop to render key and
value pairs of dictionary object result{} as cells of an HTML table.
app = Flask(__name__)
@app.route('/result')
def result():
dict = {'phy':50,'che':60,'maths':70}
if __name__ == '__main__':
app.run(debug = True)
<!doctype html>
<html>
<body>
<table border = 1>
<tr>
</tr>
{% endfor %}
</table>
</body>
</html>
Here, again the Python statements corresponding to the For loop are
enclosed in {%..%} whereas, the expressions key and value are put
inside {{ }}.
Previous Page
Next Page
app = Flask(__name__)
@app.route("/")
def index():
return render_template("index.html")
if __name__ == '__main__':
app.run(debug = True)
<html>
<head>
<script type = "text/javascript"
</head>
<body>
</body>
</html>
function sayHello() {
alert("Hello World")
}
Flask – Request Object
Advertisements
Previous Page
Next Page
The data from a client’s web page is sent to the server as a global request
object. In order to process the request data, it should be imported from
the Flask module.
args − parsed contents of query string which is part of URL after question
mark (?).
Previous Page
Next Page
We have already seen that the http method can be specified in URL rule.
The Form data received by the triggered function can collect it in the
form of a dictionary object and forward it to a template to render it on a
corresponding web page.
app = Flask(__name__)
@app.route('/')
def student():
return render_template('student.html')
def result():
if request.method == 'POST':
result = request.form
if __name__ == '__main__':
app.run(debug = True)
<html>
<body>
</form>
</body>
</html>
<!doctype html>
<html>
<body>
<tr>
</tr>
{% endfor %}
</table>
</body>
</html>
Run the Python script and enter the URL http://localhost:5000/ in the
browser.
Previous Page
Next Page
@app.route('/')
def index():
return render_template('index.html')
<html>
<body>
</form>
</body>
</html>
def setcookie():
if request.method == 'POST':
user = request.form['nm']
resp = make_response(render_template('readcookie.html'))
resp.set_cookie('userID', user)
return resp
@app.route('/getcookie')
def getcookie():
name = request.cookies.get('userID')
Previous Page
Next Page
A session with each client is assigned a Session ID. The Session data is
stored on top of cookies and the server signs them cryptographically. For
this encryption, a Flask application needs a defined SECRET_KEY.
@app.route('/')
def index():
if 'username' in session:
username = session['username']
def login():
if request.method == 'POST':
session['username'] = request.form['username']
return redirect(url_for('index'))
return '''
</form>
'''
@app.route('/logout')
def logout():
session.pop('username', None)
return redirect(url_for('index'))
Run the application and visit the homepage. (Ensure to
set secret_key of the application)
app = Flask(__name__)
The output will be displayed as shown below. Click the link “click here
to log in”.
Previous Page
Next Page
HTTP_300_MULTIPLE_CHOICES
HTTP_301_MOVED_PERMANENTLY
HTTP_302_FOUND
HTTP_303_SEE_OTHER
HTTP_304_NOT_MODIFIED
HTTP_305_USE_PROXY
HTTP_306_RESERVED
HTTP_307_TEMPORARY_REDIRECT
app = Flask(__name__)
@app.route('/')
def index():
return render_template('log_in.html')
def login():
request.form['username'] == 'admin' :
return redirect(url_for('success'))
return redirect(url_for('index'))
@app.route('/success')
def success():
if __name__ == '__main__':
app.run(debug = True)
Let us make a slight change in the login() function in the above code.
Instead of re-displaying the login page, if ‘Unauthourized’ page is to be
displayed, replace it with call to abort(401).
app = Flask(__name__)
@app.route('/')
def index():
return render_template('log_in.html')
def login():
if request.method == 'POST':
if request.form['username'] == 'admin' :
return redirect(url_for('success'))
else:
abort(401)
else:
return redirect(url_for('index'))
@app.route('/success')
def success():
app.run(debug = True)
Flask – Message Flashing
Advertisements
Previous Page
Next Page
Here,
{% if messages %}
{% endfor %}
{% endif %}
{% endwith %}
@app.route('/')
def index():
return render_template('index.html')
The link leads a user to ‘/login’ URL which displays a login form. When
submitted, the login() view function verifies a username and password
and accordingly flashes a ‘success’ message or creates ‘error’ variable.
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or \
request.form['password'] != 'admin':
else:
return redirect(url_for('index'))
<html>
<body>
<h1>Login</h1>
{% if error %}
<p><strong>Error:</strong> {{ error }}
{% endif %}
<dl>
<dt>Username:</dt>
<dd>
</dd>
<dt>Password:</dt>
</dl>
</form>
</body>
</html>
<html>
<head>
</head>
<body>
{% if messages %}
<ul>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<b>log in?</b></a></p>
</body>
</html>
Flash.py
from flask import Flask, flash, redirect, render_template, request, url_for
app = Flask(__name__)
app.secret_key = 'random string'
@app.route('/')
def index():
return render_template('index.html')
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or \
request.form['password'] != 'admin':
else:
return redirect(url_for('index'))
if __name__ == "__main__":
app.run(debug = True)
After executing the above codes, you will see the screen as shown below.
When you click on the link, you will be directed to the Login page.
The following code has ‘/upload’ URL rule that displays ‘upload.html’ from the templates
folder, and ‘/upload-file’ URL rule that calls uploader()function handling upload process.
‘upload.html’ has a file chooser button and a submit button.
<html>
<body>
<form action = "http://localhost:5000/uploader" method = "POST"
enctype = "multipart/form-data">
<input type = "file" name = "file" />
<input type = "submit"/>
</form>
</body>
</html>
<html>
<body>
<form action = "http://localhost:5000/uploader" method = "POST"
enctype = "multipart/form-data">
<input type = "file" name = "file" />
<input type = "submit"/>
</form>
</body>
</html>
You will see the screen as shown below.
Click Submit after choosing file. Form’s post method invokes ‘/upload_file’URL. The
underlying function uploader() does the save operation.
Following is the Python code of Flask application.
@app.route('/upload')
def upload_file():
return render_template('upload.html')
if __name__ == '__main__':
app.run(debug = True)
Flask – Extensions
Flask is often referred to as a micro framework, because a core functionality includes
WSGI and routing based on Werkzeug and template engine based on Jinja2. In addition,
Flask framework has support for cookie and sessions as well as web helpers like JSON,
static files etc. Obviously, this is not enough for the development of a full-fledged web
application. This is where the Flask extensions come in picture. Flask extensions give
extensibility to Flask framework.
There are a large number of Flask extensions available. A Flask extension is a Python
module, which adds specific type of support to the Flask application. Flask Extension
Registry is a directory of extensions available. The required extension can be downloaded
by pip utility.
In this tutorial, we will discuss the following important Flask extensions −
Flask Mail − provides SMTP interface to Flask application
Flask WTF − adds rendering and validation of WTForms
Flask SQLAlchemy − adds SQLAlchemy support to Flask application
Flask Sijax − Interface for Sijax - Python/jQuery library that makes AJAX easy to use in web
applications
Each type of extension usually provides extensive documentation about its usage. Since an
extension is a Python module, it needs to be imported for it to be used. Flask extensions
are generally named as flask-foo. To import,
For versions of Flask later than 0.7, you can also use the syntax −
import flaskext_compat
flaskext_compat.activate()
from flask.ext import foo
Flask – Mail
A web based application is often required to have a feature of sending
mail to the users/clients. Flask-Mail extension makes it very easy to set
up a simple interface with any email server.
1 MAIL_SERVER
2 MAIL_PORT
3 MAIL_USE_TLS
4 MAIL_USE_SSL
5 MAIL_DEBUG
6 MAIL_USERNAME
password of sender
8 MAIL_DEFAULT_SENDER
9 MAIL_MAX_EMAILS
10 MAIL_SUPPRESS_SEND
11 MAIL_ASCII_ATTACHMENTS
Mail class
It manages email-messaging requirements. The class constructor takes
the following form −
flask-mail.Mail(app = None)
1 send()
2 connect()
Opens connection with mail host
3 send_message()
Message class
It encapsulates an email message. Message class constructor has several
parameters −
flask-mail.Message(subject, recipients, body, html, sender, cc, bcc,
reply-to, date, charset, extra_headers, mail_options, rcpt_options)
Step 1 − Import Mail and Message class from flask-mail module in the
code.
from flask_mail import Mail, Message
@app.route("/")
def index():
mail.send(msg)
return "Sent"
Step 5 − The entire code is given below. Run the following script in
Python Shell and visit http://localhost:5000/.
app =Flask(__name__)
mail=Mail(app)
app.config['MAIL_SERVER']='smtp.gmail.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USERNAME'] = 'yourId@gmail.com'
app.config['MAIL_PASSWORD'] = '*****'
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True
mail = Mail(app)
@app.route("/")
def index():
msg = Message('Hello', sender = 'yourId@gmail.com', recipients =
['id1@gmail.com'])
mail.send(msg)
return "Sent"
if __name__ == '__main__':
app.run(debug = True)
Note that the built-insecurity features in Gmail service may block this
login attempt. You may have to decrease the security level. Please log in
to your Gmail account and visit this link to decrease the security.
Flask – WTF
One of the essential aspects of a web application is to present a user
interface for the user. HTML provides a <form> tag, which is used to
design an interface. A Form’s elements such as text input, radio, select
etc. can be used appropriately.
The Server side script has to recreate the form elements from http request
data. So in effect, form elements have to be defined twice – once in HTML
and again in the server side script.
Using Flask-WTF, we can define the form fields in our Python script and
render them using an HTML template. It is also possible to apply
validation to the WTF field.
1 TextField
Represents <input type = 'text'> HTML form element
2 BooleanField
3 DecimalField
4 IntegerField
5 RadioField
6 SelectField
7 TextAreaField
8 PasswordField
9 SubmitField
In addition to the ‘name’ field, a hidden field for CSRF token is created
automatically. This is to prevent Cross Site Request Forgery attack.
When rendered, this will result into an equivalent HTML script as shown
below.
app = Flask(__name__)
@app.route('/contact')
def contact():
form = ContactForm()
if __name__ == '__main__':
app.run(debug = True)
2 Email
3 IPAddress
4 Length
5 NumberRange
6 URL
We shall now apply ‘DataRequired’ validation rule for the name field in
contact form.
name = TextField("Name Of Student",[validators.Required("Please enter your name.")])
The validate() function of form object validates the form data and
throws the validation errors if validation fails. The Error messages are
sent to the template. In the HTML template, error messages are rendered
dynamically.
{% for message in form.name.errors %}
{{ message }}
{% endfor %}
SelectField
class ContactForm(Form):
your name.")])
Address = TextAreaField("Address")
Age = IntegerField("age")
('py', 'Python')])
submit = SubmitField("Send")
app = Flask(__name__)
form = ContactForm()
if request.method == 'POST':
if form.validate() == False:
else:
return render_template('success.html')
if __name__ == '__main__':
app.run(debug = True)
<!doctype html>
<html>
<body>
{% endfor %}
{% endfor %}
<form action = "http://localhost:5000/contact" method = post>
<fieldset>
<legend>Contact Form</legend>
{{ form.hidden_tag() }}
{{ form.name.label }}<br>
{{ form.name }}
<br>
{{ form.Gender.label }} {{ form.Gender }}
{{ form.Address.label }}<br>
{{ form.Address }}
<br>
{{ form.email.label }}<br>
{{ form.email }}
<br>
{{ form.Age.label }}<br>
{{ form.Age }}
<br>
{{ form.language.label }}<br>
{{ form.language }}
<br>
{{ form.submit }}
</div>
</fieldset>
</form>
</body>
</html>
Previous Page
Next Page
Python has an in-built support for SQlite. SQlite3 module is shipped with
Python distribution. For a detailed tutorial on using SQLite database in
Python, please refer to this link. In this section we shall see how a Flask
application interacts with SQLite.
import sqlite3
conn = sqlite3.connect('database.db')
conn.execute('CREATE TABLE students (name TEXT, addr TEXT, city TEXT, pin
TEXT)')
conn.close()
@app.route('/enternew')
def new_student():
return render_template('student.html')
The HTML script for ‘student.html’ is as follows −
<html>
<body>
<h3>Student Information</h3>
Name<br>
Address<br>
City<br>
PINCODE<br>
</form>
</body>
</html>
As it can be seen, form data is posted to the ‘/addrec’ URL which binds
the addrec() function.
This addrec() function retrieves the form’s data by POST method and
inserts in students table. Message corresponding to success or error in
insert operation is rendered to ‘result.html’.
def addrec():
if request.method == 'POST':
try:
nm = request.form['nm']
addr = request.form['add']
city = request.form['city']
pin = request.form['pin']
cur = con.cursor()
VALUES (?,?,?,?)",(nm,addr,city,pin) )
con.commit()
except:
con.rollback()
finally:
con.close()
<!doctype html>
<html>
<body>
</html>
@app.route('/list')
def list():
con = sql.connect("database.db")
con.row_factory = sql.Row
cur = con.cursor()
rows = cur.fetchall();
This list.html is a template, which iterates over the row set and renders
the data in an HTML table.
<!doctype html>
<html>
<body>
<thead>
<td>Name</td>
<td>Address>/td<
<td>city</td>
<td>Pincode</td>
</thead>
{% for row in rows %}
<tr>
<td>{{row["name"]}}</td>
<td>{{row["addr"]}}</td>
<td> {{ row["city"]}}</td>
<td>{{row['pin']}}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
Finally, the ‘/’ URL rule renders a ‘home.html’ which acts as the entry
point of the application.
@app.route('/')
def home():
return render_template('home.html')
app = Flask(__name__)
@app.route('/')
def home():
return render_template('home.html')
@app.route('/enternew')
def new_student():
return render_template('student.html')
def addrec():
if request.method == 'POST':
try:
nm = request.form['nm']
addr = request.form['add']
city = request.form['city']
pin = request.form['pin']
cur = con.cursor()
VALUES (?,?,?,?)",(nm,addr,city,pin) )
con.commit()
except:
con.rollback()
finally:
@app.route('/list')
def list():
con = sql.connect("database.db")
con.row_factory = sql.Row
cur = con.cursor()
rows = cur.fetchall();
if __name__ == '__main__':
app.run(debug = True)
Run this script from Python shell and as the development server starts
running. Visit http://localhost:5000/ in browser which displays a
simple menu like this −
Click ‘Add New Record’ link to open the Student Information Form.
Fill the form fields and submit it. The underlying function inserts the
record in the students table.
Go back to the home page and click ‘Show List’ link. The table showing
the sample data will be displayed.
Flask – SQLAlchemy
Advertisements
Previous Page
Next Page
Step 3 − Now create a Flask application object and set URI for the
database to be used.
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///students.sqlite3'
db = SQLAlchemy(app)
class students(db.Model):
name = db.Column(db.String(100))
city = db.Column(db.String(50))
addr = db.Column(db.String(200))
pin = db.Column(db.String(10))
self.name = name
self.city = city
self.addr = addr
self.pin = pin
You can apply a filter to the retrieved record set by using the filter
attribute. For instance, in order to retrieve records with city =
’Hyderabad’ in students table, use following statement −
Students.query.filter_by(city = ’Hyderabad’).all()
With this much of background, now we shall provide view functions for
our application to add a student data.
@app.route('/')
def show_all():
<!DOCTYPE html>
<head></head>
<body>
<h3>
SQLAlchemy example</a>
</h3>
<hr/>
{{ message }}
{%- endfor %}
</a>)</h3>
<table>
<thead>
<tr>
<th>Name</th>
<th>City</th>
<th>Address</th>
<th>Pin</th>
</tr>
</thead>
<tbody>
<tr>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
<html>
<body>
<hr/>
{{ message }}
</div>
{%- endfor %}
</form>
</body>
</html>
When the http method is detected as POST, the form data is added in
the students table and the application returns to homepage showing the
added data.
def new():
if request.method == 'POST':
else:
request.form['addr'], request.form['pin'])
db.session.add(student)
db.session.commit()
return redirect(url_for('show_all'))
return render_template('new.html')
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///students.sqlite3'
db = SQLAlchemy(app)
class students(db.Model):
name = db.Column(db.String(100))
city = db.Column(db.String(50))
addr = db.Column(db.String(200))
pin = db.Column(db.String(10))
self.name = name
self.city = city
self.addr = addr
self.pin = pin
@app.route('/')
def show_all():
def new():
if request.method == 'POST':
else:
request.form['addr'], request.form['pin'])
db.session.add(student)
db.session.commit()
return redirect(url_for('show_all'))
return render_template('new.html')
if __name__ == '__main__':
db.create_all()
app.run(debug = True)
Previous Page
Next Page
Installation
Installation of Flask-Sijax is easy.
pip install flask-sijax
Configuration
SIJAX_STATIC_PATH − the static path where you want the Sijax javascript
files to be mirrored. The default location is static/js/sijax. In this
folder, sijax.js and json2.js files are kept.
Sijax uses JSON to pass the data between the browser and the server.
This means that the browsers need either to support JSON natively or
get JSONsupport from the json2.js file.
Every Sijax handler function (like this one) receives at least one
parameter automatically, much like Python passes ‘self’ to the object
methods. The ‘obj_response’ parameter is the function's way of talking
back to the browser.
def say_hi(obj_response):
obj_response.alert('Hi there!')
g.sijax.register_callback('say_hi', say_hi)
return g.sijax.process_request()
Sijax Application
A minimal Sijax application code looks as follows −
import os
app = Flask(__name__)
app.config['SIJAX_STATIC_PATH'] = path
app.config['SIJAX_JSON_URI'] = '/static/js/sijax/json2.js'
flask_sijax.Sijax(app)
@app.route('/')
def index():
return 'Index'
@flask_sijax.route(app, '/hello')
def hello():
def say_hi(obj_response):
obj_response.alert('Hi there!')
if g.sijax.is_sijax_request:
g.sijax.register_callback('say_hi', say_hi)
return g.sijax.process_request()
return _render_template('sijaxexample.html')
if __name__ == '__main__':
app.run(debug = True)
Previous Page
Next Page
Deployment
To switch over from a development environment to a full-fledged
production environment, an application needs to be deployed on a real
web server. Depending upon what you have, there are different options
available to deploy a Flask web application.
Heroku
dotcloud
webfaction
mod_wsgi
mod_wsgi is an Apache module that provides a WSGI compliant
interface for hosting Python based web applications on Apache server.
Installing mod_wsgi
To install an official release direct from PyPi, you can run −
pip install mod_wsgi
This will start up Apache/mod_wsgi on port 8000. You can then verify
that the installation worked by pointing your browser at −
http://localhost:8000/
Make sure that yourapplication and all the libraries that are in use are
on the python load path.
Configuring Apache
You need to tell mod_wsgi, the location of your application.
<VirtualHost *>
ServerName example.com
WSGIScriptAlias / C:\yourdir\yourapp.wsgi
<Directory C:\yourdir>
Order deny,allow
</Directory>
</VirtualHost>
Gunicorn
Tornado
Gevent
Twisted Web
Flask – FastCGI
Advertisements
Previous Page
Next Page
Configuring FastCGI
First, you need to create the FastCGI server file. Let us call
it yourapplication.fcgi.
if __name__ == '__main__':
WSGIServer(app).run()
Configuring Apache
For a basic Apache deployment, your .fcgi file will appear in your
application URL e.g. example.com/yourapplication.fcgi/hello/.
There are few ways to configure your application so
that yourapplication.fcgi does not appear in the URL.
<VirtualHost *>
ServerName example.com
ScriptAlias / /path/to/yourapplication.fcgi/
</VirtualHost>
Configuring lighttpd
Basic configuration of lighttpd looks like this −
"max-procs" => 1
)))
alias.url = (
url.rewrite-once = (