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!

Login authentication with Flask

flask-logo
The Flask Logo
In this tutorial you will learn how to build a login web app with Python using Flask.

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 index():
    return "Hello World!"
 
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=4000)

Finally run the web app using this command:

$ python hello.py

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

Building a Flask login screen

Create this Python file and save it as app.py:

from flask import Flask
from flask import Flask, flash, redirect, render_template, request, session, abort
import os
 
app = Flask(__name__)
 
@app.route('/')
def home():
    if not session.get('logged_in'):
        return render_template('login.html')
    else:
        return "Hello Boss!"
 
@app.route('/login', methods=['POST'])
def do_admin_login():
    if request.form['password'] == 'password' and request.form['username'] == 'admin':
        session['logged_in'] = True
    else:
        flash('wrong password!')
    return home()
 
if __name__ == "__main__":
    app.secret_key = os.urandom(12)
    app.run(debug=True,host='0.0.0.0', port=4000)

There are two routes (paths you can see in your browser URL bar) created here:

@app.route('/')
@app.route('/login', methods=['POST'])

The first one displays the login screen or the home screen, based on the condition if you are logged in. The second route validates the login variables on login.

We create the directory /templates/. Create the file /templates/login.html with this code:

{% block body %}
{% if session['logged_in'] %}
<p>You're logged in already!</p>
{% else %}
<form action="/login" method="POST">
  <input type="username" name="username" placeholder="Username">
  <input type="password" name="password" placeholder="Password">
  <input type="submit" value="Log in">
</form>
{% endif %}
{% endblock %}

Run the web app using this command:

$ python hello.py

Open http://localhost:4000/ in your webbrowser, and the login screen should appear. The login credentials are shown in the do_admin_login() function.

Pythonspot.com Login Screen Python
Pythonspot.com Login Screen Python

Making it look amazing

While functional, the login screen looks like an early 90s User Interface (UI). We picked a random login template from codepen.io. We create the directory /static/ with the file style.css.

* {
box-sizing: border-box;
}
 
*:focus {
	outline: none;
}
body {
font-family: Arial;
background-color: #3498DB;
padding: 50px;
}
.login {
margin: 20px auto;
width: 300px;
}
.login-screen {
background-color: #FFF;
padding: 20px;
border-radius: 5px
}
 
.app-title {
text-align: center;
color: #777;
}
 
.login-form {
text-align: center;
}
.control-group {
margin-bottom: 10px;
}
 
input {
text-align: center;
background-color: #ECF0F1;
border: 2px solid transparent;
border-radius: 3px;
font-size: 16px;
font-weight: 200;
padding: 10px 0;
width: 250px;
transition: border .5s;
}
 
input:focus {
border: 2px solid #3498DB;
box-shadow: none;
}
 
.btn {
  border: 2px solid transparent;
  background: #3498DB;
  color: #ffffff;
  font-size: 16px;
  line-height: 25px;
  padding: 10px 0;
  text-decoration: none;
  text-shadow: none;
  border-radius: 3px;
  box-shadow: none;
  transition: 0.25s;
  display: block;
  width: 250px;
  margin: 0 auto;
}
 
.btn:hover {
  background-color: #2980B9;
}
 
.login-link {
  font-size: 12px;
  color: #444;
  display: block;
	margin-top: 12px;
}

Modify the login.html template as:

<link rel="stylesheet" href="/static/style.css" type="text/css">
{% block body %}
{% if session['logged_in'] %}
<p>You're logged in already!</p>
{% else %}
 
 
<form action="/login" method="POST">
	<div class="login">
		<div class="login-screen">
			<div class="app-title">
				<h1>Login</h1>
			</div>
 
			<div class="login-form">
				<div class="control-group">
				<input type="text" class="login-field" value="" placeholder="username" name="username">
				<label class="login-field-icon fui-user" for="login-name"></label>
				</div>
 
				<div class="control-group">
				<input type="password" class="login-field" value="" placeholder="password" name="password">
				<label class="login-field-icon fui-lock" for="login-pass"></label>
				</div>
 
                <input type="submit" value="Log in" class="btn btn-primary btn-large btn-block" >
			    <br>
			</div>
		</div>
	</div>
</form>
 
{% endif %}
{% endblock %}

Once you restart the application this screen should appear:

Python login screen Flask
Python login screen Flask

Awesome, ain’t it? 🙂

What about logout?

As you may have seen, there is no logout button or functionality. Creating that is very easy. The solution proposed below is only one of the many solutions. We create a new route /logout which directs to the function logout(). This function clears the session variable and returns to the login screen.

@app.route("/logout")
def logout():
    session['logged_in'] = False
    return home()

The full code:

from flask import Flask
from flask import Flask, flash, redirect, render_template, request, session, abort
import os
 
app = Flask(__name__)
 
@app.route('/')
def home():
    if not session.get('logged_in'):
        return render_template('login.html')
    else:
        return "Hello Boss!  <a href='/logout'>Logout</a>"
 
@app.route('/login', methods=['POST'])
def do_admin_login():
    if request.form['password'] == 'password' and request.form['username'] == 'admin':
        session['logged_in'] = True
    else:
        flash('wrong password!')
    return home()
 
@app.route("/logout")
def logout():
    session['logged_in'] = False
    return home()
 
if __name__ == "__main__":
    app.secret_key = os.urandom(12)
    app.run(debug=True,host='0.0.0.0', port=4000)

Connecting a database

If you want a multi-user login system, you should add a database layer to the application. Flask does not have out of the box database support. You have to use a third party library if you want database support. In this tutorial we will use SqlAlchemy. If you do not have that installed type:

$ sudo pip install Flask-SqlAlchemy

SQLAlchemy is an SQL toolkit and object-relational mapper (ORM) for the Python programming language. It has support for MySQL, Microsoft SQL Server and many more relational database management systems. If all of these terms are unfamiliar to you, just keep reading.

Create the file tabledef.py:

from sqlalchemy import *
from sqlalchemy import create_engine, ForeignKey
from sqlalchemy import Column, Date, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, backref
 
engine = create_engine('sqlite:///tutorial.db', echo=True)
Base = declarative_base()
 
########################################################################
class User(Base):
    """"""
    __tablename__ = "users"
 
    id = Column(Integer, primary_key=True)
    username = Column(String)
    password = Column(String)
 
    #----------------------------------------------------------------------
    def __init__(self, username, password):
        """"""
        self.username = username
        self.password = password
 
# create tables
Base.metadata.create_all(engine)

Execute it with:

python tabledef.py

This file will create the database structure. Inside the directory you will find a file called tutorial.db. Create a file called dummy.py which will contain this code:

import datetime
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from tabledef import *
 
engine = create_engine('sqlite:///tutorial.db', echo=True)
 
# create a Session
Session = sessionmaker(bind=engine)
session = Session()
 
user = User("admin","password")
session.add(user)
 
user = User("python","python")
session.add(user)
 
user = User("jumpiness","python")
session.add(user)
 
# commit the record the database
session.commit()
 
session.commit()

Execute:

$ python dummy.py

This will put dummy data into your database. Finally we update our app.py

Validating the login credentials with SqlAlchemy
The next step is to write the functionality that validates the user and password exist in the database. Using SqlAlchemy we can do this (dummy/pseudo code):

@app.route('/test')
def test():
 
    POST_USERNAME = "python"
    POST_PASSWORD = "python"
 
    Session = sessionmaker(bind=engine)
    s = Session()
    query = s.query(User).filter(User.username.in_([POST_USERNAME]), User.password.in_([POST_PASSWORD]) )
    result = query.first()
    if result:
        return "Object found"
    else:
        return "Object not found " + POST_USERNAME + " " + POST_PASSWORD

We use SqlAlchemys Oject Relational Mapping (ORM). We map the objects to relational database tables and vice versa. The definition (User) is given in tabledef.py. The s.query function is where the query is build. We have two conditions: the username and password must match. The query.first() returns true if the object exists, false if it does not. This gives us this total code:

from flask import Flask
from flask import Flask, flash, redirect, render_template, request, session, abort
import os
from sqlalchemy.orm import sessionmaker
from tabledef import *
engine = create_engine('sqlite:///tutorial.db', echo=True)
 
app = Flask(__name__)
 
@app.route('/')
def home():
    if not session.get('logged_in'):
        return render_template('login.html')
    else:
        return "Hello Boss!  <a href='/logout'>Logout</a>"
 
@app.route('/login', methods=['POST'])
def do_admin_login():
 
    POST_USERNAME = str(request.form['username'])
    POST_PASSWORD = str(request.form['password'])
 
    Session = sessionmaker(bind=engine)
    s = Session()
    query = s.query(User).filter(User.username.in_([POST_USERNAME]), User.password.in_([POST_PASSWORD]) )
    result = query.first()
    if result:
        session['logged_in'] = True
    else:
        flash('wrong password!')
    return home()
 
@app.route("/logout")
def logout():
    session['logged_in'] = False
    return home()
 
if __name__ == "__main__":
    app.secret_key = os.urandom(12)
    app.run(debug=True,host='0.0.0.0', port=4000)

You can now login with any user defined in the database table.

What about security?

We have demonstrated a simple login app above. However, it is your job to properly secure it. There are many guys out there that are going to try to break into your app.

Download Flask Examples

Best practices:

  • Hash your database passwords. Don’t store them in plain text.
  • Secure the connection, use HTTPS.
  • Log the failed login attempts.
  • Use captcha to prevent brute force of logins.
  • Others? write them in comments.

 

Posts navigation

1 2