Flask getting started: Hello World

In this tutorial you’ll learn how to build a web app with Python. 

We’ll use a micro-framework called Flask. It has a small core but is extensible with many plugins such as SQLAlchemy, Babel, CouchDB, MongoDB etc.  

Some Flask example apps are:

Related course
Complete Python Web Course: Build 8 Python Web Apps

Why Flask?

  • easy to use.
  • built in development server and debugger
  • integrated unit testing support
  • RESTful request dispatching
  • uses Jinja2 templating
  • support for secure cookies (client side sessions)
  • 100% WSGI 1.0 compliant
  • Unicode based
  • extensively documented

Download Flask Examples

Installing Flask

Install Flask using the command below:

pip install Flask

Flask hello world app

Create a file called hello.py

from flask import Flask
app = Flask(__name__)
 
@app.route("/")
def hello():
    return "Hello World!"
 
if __name__ == "__main__":
    app.run()

Finally run the web app using this command:

$ python hello.py
* Running on http://localhost:5000/

Open http://localhost:5000/ in your webbrowser, and “Hello World!” should appear.

Download Flask Examples
 

Flask with static html files

You can use the Flask framework and use static files together.

Flask will give you URL routing, many features and all the Python benefits.

You may want an application that is partly dynamic and partly static. Or you may simply want to browse with URL routing. In this article we will teach you how to load static HTML files with Flask.

Related course
Complete Python Web Course: Build 8 Python Web Apps

Flask static files example

Create a file called app.py with this contents:

from flask import Flask, render_template
 
app = Flask(__name__)
 
@app.route('/<string:page_name>/')
def render_static(page_name):
    return render_template('%s.html' % page_name)
 
if __name__ == '__main__':
    app.run()

This application initializes a Flask app with the method:

app.run()

The app creates an URL route for any possible page and links that to static html files with:

@app.route('/<string:page_name>/')
def render_static(page_name):
    return render_template('%s.html' % page_name)

Create a directory /templates/ and add the file hello.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
 
<html>
<head>
<title>Hello World Template</title>
</head>
<body>
Hello World
</body>
</html>

Start the server with:

$ python app.py 
* Running on http://127.0.0.1:5000/

Then any .html file is accesible using URL routing.

For example the static file hello.html can be accessed using http://127.0.0.1:5000/hello. You can store any css file in the /static/ directory.

Download Flask Examples

Jinja2 Template engine

Jinja2 is a template engine for Python.  You can use it when rendering data to web pages.  For every link you visit, you want to show the data with the formatting. By using a template engine we can seperate display logic (html, css) from the actual Python code. Let’s start with an example

Related course
Complete Python Web Course: Build 8 Python Web Apps

Getting started with Jinja2
Create the directories:

  • /app
  • /app/templates

And create the file user.html in /app/templates:

<title>{% block title %}{% endblock %}</title>
<ul>
{% for user in users %}
  <li>{{ user }}</a></li>
{% endfor %}
</ul>

Then create the code app.py  in /app/app.py:

from flask import Flask, flash, redirect, render_template, request
from random import randint
 
app = Flask(__name__)
 
@app.route("/")
def index():
    return "Flask App!"
 
@app.route("/user/")
def hello():
 
    users = [ "Frank", "Steve", "Alice", "Bruce" ]
    return render_template(
        'user.html', **locals())
 
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8080)

Finally execute with:

python app.py
 * Running on http://0.0.0.0:8080/

You can then open http://127.0.0.1:8080/user/  in your browser. This will output the data formatted according to html:

jinja2
Jinja2 Template Engine Output

About Jinja
A Jinja2 template is simply a text file that does not need to have a specific extension such as .html, .xml.
A template may contain tags and special delimiters:

Delimiters Usage
{% … %} Statements
{{ … }} Expressions to print to the template output
{# … #} Comments not included in the template output
# … ## Line Statements

In the example above we have two statements and one expression.  We have not included any comments.

Base template and child templates
A Jinja2 template can extend a base template. On a webpage with many sites you may want these pages look similar.  In /templates/ create a file called base.html with this code:

<!DOCTYPE html>
<html lang="en">
<head>
    {% block head %}
    <link rel="stylesheet" href="style.css" />
    <title>{% block title %}{% endblock %} - My Webpage</title>
    {% endblock %}
</head>
<body>
    <div id="content">{% block content %}{% endblock %}</div>
    <div id="footer">
        {% block footer %}
        Copyright 2015 by <a href="https://pythonspot.com/">pythonspot</a>.
        {% endblock %}
    </div>
</body>
</html>

We did not set a style.css, but you could set one. Change /templates/user.html to:

{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
    {{ super() }}
    <style type="text/css">
        .important { color: #336699; }
    </style>
{% endblock %}
{% block content %}
    <h1>Users</h1>
    <p class="important">
      <ul>
      {% for user in users %}
          <li>{{ user }}</a></li>
      {% endfor %}
      </ul>
 
    </p>
{% endblock %}

Restart the app with:

python app.py
 * Running on http://0.0.0.0:8080/

Output:

template jinja
Flask Jinja template engine

Flask and great looking charts using Chart.js

Flask piechart
Flask webapp with pie chart
In this article you will learn how to create great looking charts using Chart.js and Flask.

Chart.js is a javascript library to create simple and clean charts. All of them are HTML5 based, responsive, modular, interactive and there are in total 6 charts.

Related courses

Creating a bar chart app with Flask

We will start by creating a web application that displays a bar chart from a Python array. Create a directory /templates/ and add the file chart.html with this content:

< !DOCTYPE html><html lang="en"><head>   <meta charset="utf-8" />   <title>Chart.js </title>      <!-- import plugin script -->   <script src='static/Chart.min.js'></script>   </head><body>
<h1>Flask Chart.js</h1><!-- bar chart canvas element --><canvas id="chart" width="600" height="400"></canvas>
<script>
   // bar chart data
   var barData = {
   labels : [{% for item in labels %}
                  "{{item}}",
              {% endfor %}],
   datasets : [
      {
            fillColor: "rgba(151,187,205,0.2)",
            strokeColor: "rgba(151,187,205,1)",
            pointColor: "rgba(151,187,205,1)",
         data : [{% for item in values %}
                      {{item}},
                    {% endfor %}]
      }
      ]
   }
 
   // get bar chart canvas
   var mychart = document.getElementById("chart").getContext("2d");
 
   steps = 10
   max = 10
   // draw bar chart
   new Chart(mychart).Bar(barData, {
        scaleOverride: true,
        scaleSteps: steps,
        scaleStepWidth: Math.ceil(max / steps),
        scaleStartValue: 0,
        scaleShowVerticalLines: true,
        scaleShowGridLines : true,
        barShowStroke : true,
        scaleShowLabels: true
   });
 
</script>
</body></html>

Create the directory /static/ and add the file Chart.min.js to it. You can get it either from the Chart.js website or use the link. Finally go into the home directory and create app.py with this contents:

from flask import Flask
from flask import Markup
from flask import Flask
from flask import render_template
app = Flask(__name__)
 
@app.route("/")
def chart():
    labels = ["January","February","March","April","May","June","July","August"]
    values = [10,9,8,7,6,4,7,8]
    return render_template('chart.html', values=values, labels=labels)
 
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5001)

Finally run:

python app.py
Open http://127.0.0.1:5001/ and you will see the array values[] plotted with the data in labels[].
We simply pass these two arrays to render_template(). This means that most of the magic occurs in the template. Chart.js is a client-side javascript library which is why our app.py is very minimal.
Result:
Flask barchart
Flask barchart

Continue reading “Flask and great looking charts using Chart.js”

Flask Web App with Python (beginners tutorial)

python-flask-webap
Python app created with Flask

In this tutorial you’ll learn how to build a web app with Python. We’ll use a micro-framework called Flask.

Why Flask?

  • easy to use.
  • built in development server and debugger
  • integrated unit testing support
  • RESTful request dispatching
  • uses Jinja2 templating
  • support for secure cookies (client side sessions)
  • 100% WSGI 1.0 compliant
  • Unicode based
  • extensively documented

 
Related course:
Complete Python Web Course: Build 8 Python Web Apps

Installing Flask

Install Flask using the command below:

$ pip install Flask

Create a file called hello.py

from flask import Flask
app = Flask(__name__)
 
@app.route("/")
def hello():
    return "Hello World!"
 
if __name__ == "__main__":
    app.run()

Finally run the web app using this command:

$ python hello.py
 * Running on http://localhost:5000/

Open http://localhost:5000/ in your webbrowser, and “Hello World!” should appear.

Creating URL routes

URL Routing makes URLs in your Web app easy to remember. We will now create some URL routes:

/hello
/members/
/members/name/

Copy the code below and save it as app.py

from flask import Flask
app = Flask(__name__)
 
@app.route("/")
def index():
    return "Index!"
 
@app.route("/hello")
def hello():
    return "Hello World!"
 
@app.route("/members")
def members():
    return "Members"
 
@app.route("/members/<string:name>/")
def getMember(name):
    return name
 
if __name__ == "__main__":
    app.run()

Restart the application using:

$ python hello.py
 * Running on http://localhost:5000/

Try the URLs in your browser:

python-flask-webapp
python-flask-webapp

Style Flask Pages

We will separate code and User Interface using a technique called Templates. We make the directory called /templates/ and create the template:

<h1>Hello {{name}}</h1>

The Python Flask app with have a new URL route. We have changed the default port to 80, the default HTTP port:

from flask import Flask, flash, redirect, render_template, request, session, abort
 
app = Flask(__name__)
 
@app.route("/")
def index():
    return "Flask App!"
 
@app.route("/hello/<string:name>/")
def hello(name):
    return render_template(
        'test.html',name=name)
 
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

You can then open : http://127.0.0.1/hello/Jackson/

Styling the template
Do you want some better looking template? We modify the file:

{% extends "layout.html" %}
{% block body %}
 
<div class="block1">
<h1>Hello {{name}}!</h1>
  <h2>Here is an interesting quote for you: </h2>
  <p>
"The limits of my language are the limits of my mind. All I know is what I have words for."
  </p>
<img src="http://www.naturalprogramming.com/images/smilingpython.gif">
</div>
{% endblock %}

We then create layout.html which defines the look of the page. (You may want to split the stylesheet and layout.html file). Copy this as layout.html

<html>
<head>
    <title>Website</title>
<style>
@import url(http://fonts.googleapis.com/css?family=Amatic+SC:700);
 
body{
    text-align: center;    
}
h1{
    font-family: 'Amatic SC', cursive;
    font-weight: normal;
    color: #8ac640;
    font-size: 2.5em;
}
 
</style>
 
</head>
<body>
 {% block body %}{% endblock %}
 
</body>
</html>

Restart the App and open the url. http://127.0.0.1/hello/Jackson/
You can pick any name other than Jackson.

python-webapp-flask
python webapp flask

Passing Variables

Lets display random quotes instead of always the same quote. We will need to pass both the name variable and the quote variable. To pass multiple variables to the function, we simply do this:

    return render_template(
        'test.html',**locals())

Our new test.html template will look like this:

{% extends "layout.html" %}
{% block body %}
 
<div class="block1">
<h1>Hello {{name}}!</h1>
  <h2>Here is an interesting quote for you: </h2>
  <p>
{{quote}}
  </p>
<img src="http://www.naturalprogramming.com/images/smilingpython.gif">
</div>
{% endblock %}

We will need to pick a random quote. To do so, we use this code:

    quotes = [ "'If people do not believe that mathematics is simple, it is only because they do not realize how complicated life is.' -- John Louis von Neumann ",
               "'Computer science is no more about computers than astronomy is about telescopes' --  Edsger Dijkstra ",
               "'To understand recursion you must first understand recursion..' -- Unknown",
               "'You look at things that are and ask, why? I dream of things that never were and ask, why not?' -- Unknown",
               "'Mathematics is the key and door to the sciences.' -- Galileo Galilei",
               "'Not everyone will understand your journey. Thats fine. Its not their journey to make sense of. Its yours.' -- Unknown"  ]
    randomNumber = randint(0,len(quotes)-1) 
    quote = quotes[randomNumber]

The first thing you see is we have defined an array of multiples quotes. These can be accessed as quote[0], quote[1], quote[2] and so on. The function randint() returns a random number between 0 and the total number of quotes, one is subtracted because we start counting from zero. Finally we set the quote variable to the quote the computer has chosen. Copy the code below to app.py:

from flask import Flask, flash, redirect, render_template, request, session, abort
from random import randint
 
app = Flask(__name__)
 
@app.route("/")
def index():
    return "Flask App!"
 
#@app.route("/hello/<string:name>")
@app.route("/hello/<string:name>/")
def hello(name):
#    return name
    quotes = [ "'If people do not believe that mathematics is simple, it is only because they do not realize how complicated life is.' -- John Louis von Neumann ",
               "'Computer science is no more about computers than astronomy is about telescopes' --  Edsger Dijkstra ",
               "'To understand recursion you must first understand recursion..' -- Unknown",
               "'You look at things that are and ask, why? I dream of things that never were and ask, why not?' -- Unknown",
               "'Mathematics is the key and door to the sciences.' -- Galileo Galilei",
               "'Not everyone will understand your journey. Thats fine. Its not their journey to make sense of. Its yours.' -- Unknown"  ]
    randomNumber = randint(0,len(quotes)-1) 
    quote = quotes[randomNumber] 
 
    return render_template(
        'test.html',**locals())
 
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

When you restart the application it will return one of these quotes at random.

python-flask-webap
python flask webap

Download App and more Flask Examples

Whats next?
You could link your site with a database system such as MySQL, MariaDb or SQLite. You can find an SQLite tutorial here. Enjoy creating your application!

Flask web forms

Flask wtforms
Flask web form
In this tutorial you will learn how to do form validation with Flask. Forms play an important role in all web applications.

We use WTForms, a module for validation of forms. We will start with a simple form containing one field asking for a name.

Related course:
Complete Python Web Course: Build 8 Python Web Apps

Flask web forms

We create this in code:

from flask import Flask, render_template, flash, request
from wtforms import Form, TextField, TextAreaField, validators, StringField, SubmitField
 
# App config.
DEBUG = True
app = Flask(__name__)
app.config.from_object(__name__)
app.config['SECRET_KEY'] = '7d441f27d441f27567d441f2b6176a'
 
class ReusableForm(Form):
    name = TextField('Name:', validators=[validators.required()])
 
 
@app.route("/", methods=['GET', 'POST'])
def hello():
    form = ReusableForm(request.form)
 
    print form.errors
    if request.method == 'POST':
        name=request.form['name']
        print name
 
        if form.validate():
            # Save the comment here.
            flash('Hello ' + name)
        else:
            flash('All the form fields are required. ')
 
    return render_template('hello.html', form=form)
 
if __name__ == "__main__":
    app.run()

We then create the template hello.html in the /templates/ directory:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <head>
        <title>Reusable Form Demo</title>
    </head>
    <body>
        {% with messages = get_flashed_messages(with_categories=true) %}
            {% if messages %}
                <ul>
                    {% for message in messages %}
                        <li>{{ message[1] }}</li>
                    {% endfor %}
                </ul>
            {% endif %}
        {% endwith %}
        <form action="" method="post">
            {{ form.csrf }}
 
            <div class="input text">
                {{ form.name.label }} {{ form.name }}
            </div>
 
            <div class="input submit">
                <input type="submit" value="Submit" />
            </div>
        </form>
    </body>
</html>

Start the application and open it in your webbrowser at http://127.0.0.1:5000.

python miniapp.py 
 * Running on http://127.0.0.1:5000/
 * Restarting with reloader

If you will submit an empty form, you will get an error. But if you enter your name, it will greet you. Form validation is handled by the wtforms module, but because we gave the argument

name = TextField('Name:', validators=[validators.required()])

the field cannot be empty. Other parameters can be given here.

python wtforms
Python wtforms, text field validation. The app returns the name if entered

css with Flask

We use bootstrap to style the form.Bootstrap is a popular HTML, CSS, and JS framework for developing responsive, mobile first projects on the web. It makes front-end web development faster and easier. The output will be:

Flask wtforms
Flask wtforms

You can get the bootstrap files from http://getbootstrap.com/getting-started/#download and extract them in a new directory /static/. The code remains almost the same, but the template is changed. Code:

from flask import Flask, render_template, flash, request
from wtforms import Form, TextField, TextAreaField, validators, StringField, SubmitField
 
# App config.
DEBUG = True
app = Flask(__name__)
app.config.from_object(__name__)
app.config['SECRET_KEY'] = '7d441f27d441f27567d441f2b6176a'
 
class ReusableForm(Form):
    name = TextField('Name:', validators=[validators.required()])
 
 
@app.route("/", methods=['GET', 'POST'])
def hello():
    form = ReusableForm(request.form)
 
    print form.errors
    if request.method == 'POST':
        name=request.form['name']
        print name
 
        if form.validate():
            # Save the comment here.
            flash('Hello ' + name)
        else:
            flash('Error: All the form fields are required. ')
 
    return render_template('hello.html', form=form)
 
if __name__ == "__main__":
    app.run()

We added bootstrap to the template hello.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <head>
        <title>Reusable Form Demo</title>
       <link rel="stylesheet" media="screen" href ="static/bootstrap.min.css">
       <link rel="stylesheet" href="static/bootstrap-theme.min.css">
       <meta name="viewport" content = "width=device-width, initial-scale=1.0">
 
    </head>
    <body>
 
 
<div class="container">
 
 
  <h2>Flask Web Form</h2>
  <form  action="" method="post" role="form">
    {{ form.csrf }}
    <div class="form-group">
      <label for="name">Name:</label>
      <input type="text" class="form-control" id="name" name="name" placeholder="What's your name?">
    </div>
    <button type="submit" class="btn btn-success">Submit</button>
  </form>
 
  <br>
        {% with messages = get_flashed_messages(with_categories=true) %}
            {% if messages %}
 
        {% for message in messages %}
            {% if "Error" not in message[1]: %}
                <div class="alert alert-info">
                <strong>Success! </strong> {{ message[1] }}
                </div>
            {% endif %}
 
            {% if "Error" in message[1]: %}
                <div class="alert alert-warning">
                {{ message[1] }}
                </div>
            {% endif %}
        {% endfor %}
            {% endif %}
        {% endwith %}
 
</div>
<br>      
</div>
</div>
</body>
</html>

Flask registration form

We use the same principle to create a registration form asking for name, email and password. We update the Form class:

class ReusableForm(Form):
    name = TextField('Name:', validators=[validators.required()])
    email = TextField('Email:', validators=[validators.required(), validators.Length(min=6, max=35)])
    password = TextField('Password:', validators=[validators.required(), validators.Length(min=3, max=35)])
 
    def reset(self):
        blankData = MultiDict([ ('csrf', self.reset_csrf() ) ])
        self.process(blankData)

And we can get the variables passed using:

        name=request.form['name']
        password=request.form['password']
        email=request.form['email']

Full code:

from flask import Flask, render_template, flash, request
from wtforms import Form, TextField, TextAreaField, validators, StringField, SubmitField
 
# App config.
DEBUG = True
app = Flask(__name__)
app.config.from_object(__name__)
app.config['SECRET_KEY'] = '7d441f27d441f27567d441f2b6176a'
 
class ReusableForm(Form):
    name = TextField('Name:', validators=[validators.required()])
    email = TextField('Email:', validators=[validators.required(), validators.Length(min=6, max=35)])
    password = TextField('Password:', validators=[validators.required(), validators.Length(min=3, max=35)])
 
 
@app.route("/", methods=['GET', 'POST'])
def hello():
    form = ReusableForm(request.form)
 
    print form.errors
    if request.method == 'POST':
        name=request.form['name']
        password=request.form['password']
        email=request.form['email']
        print name, " ", email, " ", password
 
        if form.validate():
            # Save the comment here.
            flash('Thanks for registration ' + name)
        else:
            flash('Error: All the form fields are required. ')
 
    return render_template('hello.html', form=form)
 
if __name__ == "__main__":
    app.run()

Update the template hello.html with this code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <head>
        <title>Reusable Form Demo</title>
       <link rel="stylesheet" media="screen" href ="static/bootstrap.min.css">
       <link rel="stylesheet" href="static/bootstrap-theme.min.css">
       <meta name="viewport" content = "width=device-width, initial-scale=1.0">
 
    </head>
    <body>
 
 
<div class="container">
 
 
  <h2>Flask Web Form</h2>
  <form  action="" method="post" role="form">
    {{ form.csrf }}
    <div class="form-group">
      <label for="name">Name:</label>
      <input type="text" class="form-control" id="name" name="name" placeholder="What's your name?">
      <br>
      <label for="email">Email:</label>
      <input type="text" class="form-control" id="email" name="email" placeholder="Your email will be used to contact you.">
      <br>
      <label for="password">Password:</label>
      <input type="password" class="form-control" id="password" name="password" placeholder="Enter a password.">
 
 
    </div>
    <button type="submit" class="btn btn-success">Sign Up</button>
  </form>
 
  <br>
        {% with messages = get_flashed_messages(with_categories=true) %}
            {% if messages %}
 
        {% for message in messages %}
            {% if "Error" not in message[1]: %}
                <div class="alert alert-info">
                <strong>Success! </strong> {{ message[1] }}
                </div>
            {% endif %}
 
            {% if "Error" in message[1]: %}
                <div class="alert alert-warning">
                {{ message[1] }}
                </div>
            {% endif %}
        {% endfor %}
            {% endif %}
        {% endwith %}
 
</div>
<br>            
</div>
</div>
</body>
</html>

Output:

flask form bootstrap
flask form bootstrap

Download Flask Examples

WTForms can validate email, password, numbers and many more. For a list of validators see: http://wtforms.readthedocs.org/en/latest/validators.html

Posts navigation

1 2