Creating web applications can be exciting and there are a lot of options for you to choose from. There are numerous programming languages you can learn and use. Most of the industry we are in, application groups are utilizing frameworks instead of working with the raw language by itself. By using a framework, the time to develop an application is reduced. Depending on the choice of framework, there is usually a learning curve. Some are flat and easy to learn while others are severely sloped and hard to learn.
Flask is considered to be one of the easier frameworks to learn and to work with. It is quite powerful on its own and it leaves you a lot of room to explore and be creative. Flask is known to be a micro framework because of its lightweightness. It comes without a data layer meaning that it is up to you to hook it up to a database of your choice. It also doesn’t implement the MVC pattern meaning that if you want it, you will have to structure it and build your own models, views and controllers.
In this tutorial, we will first install Python then install Flask. With both of these components in place, we will talk a little about project structure which most call the scaffolding. We will touch on the best practices and show you two well accepted strategies. After that, we will talk a little about how templates work and what you can do with Jinga2, the template engine. We will touch on the data layer just to give you an idea of what needs to be done then we will show you two examples of a Python Flask coding.
The first example is the classic Hello World where you will return a simple string in the browser. The second example is a little more involved since web applications often need to display a HTML file filled with data or dynamic content. With just a few lines of code, you will see how working with Flask will simplify your work and why Flask is so popular.
Installing Python
Before getting too far with our Python Flask Tutorial, make sure you have Python installed. If you don’t then download an installer from Python official page. After installing Python, check to see it works by typing:
$ python3
Or if it doesn’t work, try:
$ python
If Python runs, you should get the following:
Python 3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> _
How To Install Flask
There are many ways to install Python but the best way to do so is by using virtualenv. Virtualenv is a great tool to use because it creates isolated Python development environments where you can develop all your applications in. And one of the advantages of using virtualenv is when you want to install a new Python library. If you have tried this before, you know you can mess up your environment very easily. But not with virtualenv because you can create a sandbox that utilizes the new library and it won’t affect the rest of your development. When you’re finished experimenting, you can delete the sandbox and continue with your primary development.
Installing Flask becomes easy:
$virtualenv flaskapp
After this command, a new directory flaskapp/ is created and a new copy of Python for you to use. It also installs pip which we will use shortly. We must first activate it then we can install Flask.
$ cd flaskapp
$ . bin/activate
$ pip install Flask
How to Structure a Flask Project
The first thing you will notice when you start working with Flask is that it is flexible. Not just a little flexible but a lot because you have complete freedom in setting up the project structure. Before jumping into our first application, let us explore some best practices on structuring your project.
One popular way to organize a project is by function. Here, you can organize your project by the function.
project/
__init__.py
models/
__init__.py
base.py
users.py
posts.py
…
routes/
__init__.py
home.py
account.py
dashboard.py
…
templates/
base.html
post.html
…
services/
__init__.py
google.py
mail.py
…
By structuring your project this way, anything that is like a model can be placed under the models/ folder and anything that is like a routing routine can be under the routes/ folder.
Now to start off everything, we will create an app factory in the __init__.py file under the project/ folder:
from flask import flask
def create_app()
from . import models, routes, services
app = Flask(__name__)
models.init_app(app)
routes.init_app(app)
services.init_app(app)
return app
If you don’t like this project structure, you can always structure your project by app. Lets look at how a project is structured:
project/
__init__.py
db.py
auth/
__init__.py
route.py
models.py
templates/
blog/
__init__.py
route.py
models.py
templates/
…
Here each folder is an application. If you are familiar with Django, another popular framework used with Python, you would have been familiar with an app-based structure because by default, Django is structured this way.
Templates
It is considered good design to separate presentation from business logic and templates help us achieve that. Templates contain HTML which provides content to a web page. Dynamic content is provided using placeholders or variables that are set only at run time.
We need to create a view function to render an HTML page.
from flask import render_template
from app import app
@app.route('/')
@app.route('/index')
def index():
user = {'username': 'Miguel'}
return render_template('index.html', title='Home', user=user)
The function render_template() is from the Flask framework and it invokes the Jinga2 template engine that takes the HTML in a template file and replaces all the {{…}} placeholders with arguments from the function call.
Conditional
You may ask what would happen if the title argument was not supplied or it was nil. The render_template() would simply render the HTML as-is. This may not be acceptable so luckily we have an alternative. We could put some logic in our template to do something different if an argument is missing. We do this using the following logic:
{% if title %}
<title>{{ title }} - Python Flask Class</title>
{% else %}
<title>Welcome to Python Flask Tutorial!</title>
{% endif %}
Loops
Two data types that are used frequently in Python include lists and dictionaries. Both of these data types are used to store collections of data such as users, accounts and products. When presenting collections on a web page, it helps if the template can iterate through a collection and provide the necessary HTML to render the page.
Jinga2 provides the ‘for’ control:
<body>
<h1>Hi, {{ user.username }}!</h1>
{% for account in accountss %}
<div><p>{{ account.author.username }} says: <b>{{ account.body }}</b></p></div>
{% endfor %}
</body>
The view function changes slightly:
from flask import render_template
from app import app
@app.route('/')
@app.route('/index')
def index():
user = {'username': 'John'}
accounts = [
{
'author': {'username': 'John'},
'body': 'Savings Account!'
},
{
'author': {'username': 'Jane'},
'body': 'Chequing Account'
}
]
return render_template('index.html', title='Home', user=user, accounts=accounts)
Databases
Flask does not support databases natively. This may be a blessing in disguise because it leaves it up to you to decide which one to use. Instead of being forced to use a particular database, Flask lets you decide on using either a SQL-based database or a NOSQL database.
There are two basic types of databases to use. There are relational databases that implements a SQL language and has tables, rows and columns. Then there are document based databases that uses a SQL-like syntax to access documents.
One of the best extensions for Flask is the Flask-SQLAlchemy which provides a Flask-friendly Object-Relational Mapper (ORM). ORMS allow applications to be managed using classes, objects and methods instead of tables and columns.
Add the following code in the app/__init__.py file:
from flask import Flask
from config import Config
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
from app import routes, models
Writing A “Hello, World!” Flask Application
Create a hello.py file and enter the following code:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
$ python hello.py
Then enter the following in your browser:
And the words ‘Hello World’ should appear.
Writing A Flask Application that Renders from a Template
In this example, we are going to modify the Hello World application to return the contents of a HTML file instead of just returning a text string. To do this, you are going to create a new file with some HTML in it then you are going to place it in the templates/ folder. All HTML templates must be in the templates/ folder because Flask will look there for all templates.
Create a new file and name it about.html with the following contents in it:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>About my Flask Application</title>
</head>
<body>
<h1> About Templates</h1>
<p> This is a same template that I have placed in the templates folder.</p>
<p> By putting all my templates here, Flask will automatically go here
To look for templates that will be rendered.</p>
</body>
</html>
Now place this file under the templates/ folder. Next we will have to change the application file to return the contents of a HTML file instead of a text string. Go back to the hello.py file and modify the code to the following:
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
@app.route("/about)
def about():
return render_template("about.html")
if __name__ == "__main__":
app.run()
Run the application and see what happens when you type the following in the browser:
By specifying the /about, Flask will route control to the about.html file to render.
Disclosure of Material Connection: Some of the links in the post above are “affiliate links.” This means if you click on the link and purchase the item, I will receive an affiliate commission. Regardless, I only recommend products or services I use personally and believe will add value to my readers.