1. Basics

In this tutorial, we’re going to develop an application for managing a movie collection. We’ll start by creating a simple home page containing only a title. Then, we’ll add a greeting message based on the current date to show how dynamic content is generated. Next, we’ll create another page, again containing only a title. This second page will be populated with the list of movies in later chapters. Finally, we’ll provide a link from the home page to the movie list page. In the end, the home page will look as shown in Fig. 1.1.

Screenshot of home page with message and link.

Fig. 1.1 Home page containing a greeting message and a link to the movie list page.

1.1. Applications

Using Flask, we can create a web application in just one source file. In Listing 1.1, you can see the code for a very simple application that serves only one page with only a title in it. Save this code in a file named server.py and run it using the command:

python server.py

Now, when you visit the address http://localhost:8080/ you should see the title.

Listing 1.1 Application with only a title (file: server.py, version: v0101).
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from flask import Flask


app = Flask(__name__)


@app.route("/")
def home_page():
    return "My movie collection"


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080, debug=True)

Let’s go over this code line by line:

  • Line 1: The Flask application class gets imported. Applications are instances of this class.

  • Line 4: An application of this class gets instantiated.

  • Line 13: The application gets started. The host parameter specifies that the server should be publicly available, and the port parameter specifies that it should run on port 8080. We also set the application to run in debug mode to get better feedback about errors.

    Warning

    Debug mode causes security problems. Therefore this mode should be enabled only during development.

  • Lines 7-9: A view function is defined to handle requests to the home page. It simply returns a string containing the title. The route decorator registers the / route with this function. So whenever there is a request to the / route, this function will be invoked and its result will be sent back to the client as the response.

Note that the string returned by the view function is not an HTML page, but only a string. We could return an HTML page as in:

return """<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>My movies</title>
  </head>
  <body>
    <h1>My movie collection</h1>
  </body>
</html>
"""

But this would not only make the code less readable, it would also be very difficult to maintain. The proper way to handle this is to use a template that contains the HTML markup. By default, Flask looks for template files in the templates folder; so we create a file named home.html in that folder to contain the home page template given in Listing 1.2.

Listing 1.2 Initial home page template (file: templates/home.html, version: v0102).
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>My movies - Home</title>
    <link rel="stylesheet" href="/static/mymovies.css"/>
  </head>
  <body>
    <h1>My movie collection</h1>
  </body>
</html>

Now, as shown in Listing 1.3, we can import a function for rendering a template (line 1), and the view function can call it to render the home page (line 9).

Listing 1.3 Application using a template (file: server.py, version: v0102).
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from flask import Flask, render_template


app = Flask(__name__)


@app.route("/")
def home_page():
    return render_template("home.html")


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080, debug=True)

Static files like images and style sheets are placed into the static folder. Our template (Listing 1.2) contains a style sheet reference on line 6. To make this reference work, we create the file static/mymovies.css with the contents given in Listing 1.4.

Listing 1.4 Style sheet for the application (file: static/mymovies.css, version: v0102).
1
2
3
h1 {
    color: #e9601a;
}

1.2. Dynamic Content

Let’s add a greeting message to our home page based on the current date. We first change our template to add the necessary markup (Listing 1.5, line 10).

Listing 1.5 Home page markup with dynamic greeting message (file: templates/home.html, version: v0103).
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>My movies - Home</title>
    <link rel="stylesheet" href="/static/mymovies.css"/>
  </head>
  <body>
    <h1>My movie collection</h1>
    <p>Have a nice {{ day }}!</p>
  </body>
</html>

Since the name of the current day will change between different visits, we need our template system to be able to generate the HTML output dynamically. For this purpose, we’re going to use Jinja, which is the default template system used by Flask.

In Jinja templates, the parts marked with {{ and }} will be replaced by the value of the expression they contain. The parameters in the expression have to be supplied by the view function that renders this template. In our example, the home_page function has to send a value for day as a parameter. Listing 1.6 shows how the view function decides the name of the current day (lines 11-12), and sends it to the template (line 13).

Listing 1.6 View function sending parameter (file: server.py, version: v0103).
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
from datetime import datetime

from flask import Flask, render_template


app = Flask(__name__)


@app.route("/")
def home_page():
    today = datetime.today()
    day_name = today.strftime("%A")
    return render_template("home.html", day=day_name)


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080, debug=True)

The application, as implemented so far, runs as follows:

  • An application object gets instantiated.
  • The application registers the home_page function to respond to requests for the / route.
  • The application starts running on the localhost on port 8080 and waits for requests.
  • When a request comes for http://localhost:8080/, the home_page function gets invoked.
  • This function gets the current day and renders the home page template, passing the name of the day as a parameter to it. The server sends the rendered page back to the client.
  • The client parses the response and encounters the link for the style sheet. It makes a request to http://localhost:8080/static/mymovies.css.
  • The server sends back the mymovies.css file.