This content originally appeared on Envato Tuts+ Tutorials and was authored by Lalith Polepeddi
Flask is a small and powerful web framework for Python. It's easy to learn and simple to use, enabling you to build your web app in a short amount of time.
In this article, I'll show you how to build a simple website, containing two static pages with a small amount of dynamic content. While Flask can be used for building complex, database-driven websites, starting with mostly static pages will be useful to introduce a workflow, which we can then generalize to make more complex pages in the future. Upon completion, you'll be able to use this sequence of steps to jumpstart your next Flask app.
Installing Flask
Before getting started, we need to install Flask. Because systems vary, things can sporadically go wrong during these steps. If they do, like we all do, just Google the error message or leave a comment describing the problem.
Install Virtualenv
Virtualenv is a useful tool that creates isolated Python development environments where you can do all your development work.
We'll use virtualenv to install Flask. Virtualenv is a useful tool that creates isolated Python development environments where you can do all your development work. Suppose you come across a new Python library that you'd like to try. If you install it system-wide, there is the risk of messing up other libraries that you might have installed. Instead, use virtualenv to create a sandbox, where you can install and use the library without affecting the rest of your system. You can keep using this sandbox for ongoing development work, or you can simply delete it once you've finished using it. Either way, your system remains organized and clutter-free.
It's possible that your system already has virtualenv. Refer to the command line, and try running:
1 |
$ virtualenv --version |
If you see a version number, you're good to go and you can skip to this "Install Flask" section. If the command was not found, use pip
to install virtualenv, you should already have pip installed. If running Linux or Mac OS X, the following should work for you:
Install pip
1 |
sudo apt-get install python3-pip |
Install Virtualenv
1 |
$ sudo pip install virtualenv |
If you don't have either of these commands installed, there are several tutorials online, which will show you how to install it on your system. If you're running Windows, install virualenv with pip as follows:
1 |
pip install virtualenv
|
Install Flask
After installing virtualenv
, you can create a new isolated development environment, like so:
1 |
$ virtualenv flaskapp
|
Here, virtualenv
creates a folder, flaskapp/, and sets up a clean copy of Python inside for you to use. It also installs the handy package manager, pip
.
Enter your newly created development environment and activate it so you can begin working within it.
1 |
$ cd flaskapp |
2 |
$ . bin/activate |
Now, you can safely install Flask:
1 |
pip install Flask
|
Setting up the Project Structure
Let's create a couple of folders and files within flaskapp/ to keep our web app organized.
1 |
. |
2 |
. |
3 |
├── app |
4 |
│ ├── static |
5 |
│ │ ├── css |
6 |
│ │ ├── img |
7 |
│ │ └── js |
8 |
│ ├── templates |
9 |
│ ├── routes.py |
10 |
│ └── README.md |
Within flaskapp/, create a folder, app/, to contain all your files. Inside app/, create a folder static/; this is where we'll put our web app's images, CSS, and JavaScript files, so create folders for each of those, as demonstrated above. Additionally, create another folder, templates/, to store the app's web templates. Create an empty Python file routes.py for the application logic, such as URL routing.
And no project is complete without a helpful description, so create a README.md file as well.
Now, we know where to put our project's assets, but how does everything connect together? Let's take a look at the diagram below to see the big picture:
- A user issues a request for a domain's root URL
/
to go to its home page -
routes.py maps the URL
/
to a Python function - The Python function finds a web template living in the templates/ folder.
- A web template will look in the static/ folder for any images, CSS, or JavaScript files it needs as it renders to HTML
- Rendered HTML is sent back to routes.py
- routes.py sends the HTML back to the browser
We start with a request issued from a web browser. A user types a URL into the address bar. The request hits routes.py, which has code that maps the URL to a function. The function finds a template in the templates/ folder, renders it to HTML, and sends it back to the browser. The function can optionally fetch records from a database and then pass that information on to a web template, but since we're dealing with mostly static pages in this article, we'll skip interacting with a database for now.
Now that we know our way around the project structure we set up, let's get started with making a home page for our web app.
Creating a Home Page
When you write a web app with a couple of pages, it quickly becomes annoying to write the same HTML boilerplate over and over again for each page. Furthermore, what if you need to add a new element to your app, such as a new CSS file? You would have to go into every single page and add it in. This is time consuming and error prone. Wouldn't it be nice if, instead of repeatedly writing the same HTML boilerplate, you could define your page layout just once, and then use that layout to make new pages with their own content? This is exactly what web templates do!
Web templates are simply text files that contain variables and control flow statements (
if..else
,for
, etc), and end with an.html
or.xml
extension.
The variables are replaced with your content, when the web template is evaluated. Web templates remove repetition, separate content from design, and make your application easier to maintain. In other, simpler words, web templates are awesome and you should use them! Flask uses the Jinja2 template engine; let's see how to use it.
As a first step, we'll define our page layout in a skeleton HTML document layout.html and put it inside the templates/ folder:
app/templates/layout.html
1 |
<!DOCTYPE html>
|
2 |
<html>
|
3 |
<head>
|
4 |
<title>Flask App</title> |
5 |
</head>
|
6 |
<body>
|
7 |
|
8 |
<header>
|
9 |
<div class="container"> |
10 |
<h1 class="logo">Flask App</h1> |
11 |
</div>
|
12 |
</header>
|
13 |
|
14 |
<div class="container"> |
15 |
{% block content %} |
16 |
{% endblock %} |
17 |
</div>
|
18 |
|
19 |
</body>
|
20 |
</html>
|
This is simply a regular HTML file...but what's going on with the {% block content %}{% endblock %}
part? To answer this, let's create another file home.html:
app/templates/home.html
1 |
{% extends "layout.html" %} |
2 |
{% block content %} |
3 |
<div class="jumbo"> |
4 |
<h2>Welcome to the Flask app<h2> |
5 |
<h3>This is the home page for the Flask app<h3> |
6 |
</div>
|
7 |
{% endblock %} |
The file layout.html defines an empty block, named content
, that a child template can fill in. The file home.html is a child template that inherits the markup from layout.html and fills in the "content" block with its own text. In other words, layout.html defines all of the common elements of your site, while each child template customizes it with its own content.
This all sounds cool, but how do we actually see this page? How can we type a URL in the browser and "visit" home.html? Let's refer back to the figure above. We just created the template home.html and placed it in the templates/ folder. Now, we need to map a URL to it so we can view it in the browser. Let's open up routes.py and do this:
app/routes.py
1 |
from flask import Flask, render_template |
2 |
app = Flask(__name__) |
3 |
|
4 |
@app.route('/') |
5 |
def home(): |
6 |
return render_template('home.html') |
7 |
|
8 |
if __name__ == '__main__': |
9 |
app.run(debug=True) |
That's it for routes.py. What did we do?
- First. we imported the Flask class and a function
render_template
. - Next, we created a new instance of the Flask class.
- We then mapped the URL
/
to the functionhome()
. Now, when someone visits this URL, the functionhome()
will execute. - The function
home()
uses the Flask functionrender_template()
to render the home.html template we just created from the templates/ folder to the browser. - Finally, we use
run()
to run our app on a local server. We'll set thedebug
flag totrue
, so we can view any applicable error messages if something goes wrong, and so that the local server automatically reloads after we've made changes to the code.
We're finally ready to see the fruits of our labor. Return to the command line, and type:
1 |
$ python routes.py
|
Visit http://localhost:5000/ in your favorite web browser.
When we visited http://localhost:5000/, routes.py had code in it, which mapped the URL /
to the Python function home()
. home()
found the web template home.html in the templates/ folder, rendered it to HTML, and sent it back to the browser, giving us the screen above.
Pretty neat, but this home page is a bit boring, isn't it? Let's make it look better by adding some CSS. Create a file, main.css, within static/css/, and add these rules:
static/css/main.css
1 |
body { |
2 |
margin: 0; |
3 |
padding: 0; |
4 |
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; |
5 |
color: #444; |
6 |
}
|
7 |
/*
|
8 |
* Create dark grey header with a white logo
|
9 |
*/
|
10 |
|
11 |
header { |
12 |
background-color: #2B2B2B; |
13 |
height: 35px; |
14 |
width: 100%; |
15 |
opacity: .9; |
16 |
margin-bottom: 10px; |
17 |
}
|
18 |
header h1.logo { |
19 |
margin: 0; |
20 |
font-size: 1.7em; |
21 |
color: #fff; |
22 |
text-transform: uppercase; |
23 |
float: left; |
24 |
}
|
25 |
header h1.logo:hover { |
26 |
color: #fff; |
27 |
text-decoration: none; |
28 |
}
|
29 |
/*
|
30 |
* Center the body content
|
31 |
*/
|
32 |
|
33 |
.container { |
34 |
width: 940px; |
35 |
margin: 0 auto; |
36 |
}
|
37 |
div.jumbo { |
38 |
padding: 10px 0 30px 0; |
39 |
background-color: #eeeeee; |
40 |
-webkit-border-radius: 6px; |
41 |
-moz-border-radius: 6px; |
42 |
border-radius: 6px; |
43 |
}
|
44 |
h2 { |
45 |
font-size: 3em; |
46 |
margin-top: 40px; |
47 |
text-align: center; |
48 |
letter-spacing: -2px; |
49 |
}
|
50 |
h3 { |
51 |
font-size: 1.7em; |
52 |
font-weight: 100; |
53 |
margin-top: 30px; |
54 |
text-align: center; |
55 |
letter-spacing: -1px; |
56 |
color: #999; |
57 |
}
|
Add this stylesheet to the skeleton file layout.html so that the styling applies to all of its child templates by adding this line to its <head> element:
1 |
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}">; |
We're using the Flask function, url_for
, to generate a URL path for main.css from the static folder. After adding this line in, layout.html should now look like:
app/templates/layout.html
1 |
<!DOCTYPE html>
|
2 |
<html>
|
3 |
<head>
|
4 |
<title>Flask</title> |
5 |
<strong><link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}"></strong> |
6 |
</head>
|
7 |
<body>
|
8 |
<header>
|
9 |
<div class="container"> |
10 |
<h1 class="logo">Flask App</h1> |
11 |
</div>
|
12 |
</header>
|
13 |
|
14 |
<div class="container"> |
15 |
{% block content %} |
16 |
{% endblock %} |
17 |
</div>
|
18 |
</body>
|
19 |
</html>
|
Let's switch back to the browser and refresh the page to view the result of the CSS.
That's more like it! Now, when we visit http://localhost:5000/, routes.py still maps the URL /
to the Python function home()
, and home()
still finds the web template home.html in the templates/ folder. But, since we added the CSS file main.css, the web template home.html looks in static/ to find this asset, before rendering to HTML and being sent back to the browser.
We've achieved a lot so far. We started with Fig. 1 by understanding how Flask works, and now we've seen how it all plays out, by creating a home page for our web app. Let's move on and create an About page.
Creating an About Page
In the previous section, we created a web template home.html by extending the skeleton file layout.html. We then mapped the URL /
to home.html in routes.py so we could visit it in the browser. We finished things up by adding some styling to make it look pretty. Let's repeat that process again to create an about page for our web app.
We'll begin by creating a web template, about.html, and putting it inside the templates/ folder.
app/templates/about.html
1 |
{% extends "layout.html" %} |
2 |
|
3 |
{% block content %} |
4 |
<h2>About</h2> |
5 |
<p>This is an About page for the Intro to Flask article. Don't I look good? Oh stop, you're making me blush.</p> |
6 |
{% endblock %} |
Just like before with home.html, we extend from layout.html, and then fill the content
block with our custom content.
In order to visit this page in the browser, we need to map a URL to it. Open up routes.py and add another mapping:
1 |
from flask import Flask, render_template |
2 |
|
3 |
app = Flask(__name__) |
4 |
|
5 |
@app.route('/') |
6 |
def home(): |
7 |
return render_template('home.html') |
8 |
|
9 |
@app.route('/about') |
10 |
def about(): |
11 |
return render_template('about.html') |
12 |
|
13 |
if __name__ == '__main__': |
14 |
app.run(debug=True) |
We mapped the URL /about
to the function about()
. Now we can open up the browser and go to http://localhost:5000/about and check out our newly created page.
Adding Navigation
Most websites have links to their main pages within the header or footer of the document. These links are usually visible across all pages of a website. Let's open up the skeleton file, layout.html. and add these links so they show up in all of the child templates. Specifically, let's add a <nav>
element inside the <header>
element:
app/templates/layout.html
1 |
... |
2 |
<header>
|
3 |
<div class="container"> |
4 |
<h1 class="logo">Flask App</h1> |
5 |
<strong><nav>
|
6 |
<ul class="menu"> |
7 |
<li><a href="{{ url_for('home') }}">Home</a></li> |
8 |
<li><a href="{{ url_for('about') }}">About</a></li> |
9 |
</ul>
|
10 |
</nav></strong>
|
11 |
</div>
|
12 |
</header>
|
13 |
... |
Once again, we use the Flask function url_for
to generate URLs.
Next, add some more style rules to main.css to make these new navigation elements look good:
app/static/css/main.css
1 |
...
|
2 |
/*
|
3 |
* Display navigation links inline
|
4 |
*/
|
5 |
.menu { |
6 |
float: right; |
7 |
margin-top: 8px; |
8 |
}
|
9 |
.menu li { |
10 |
display: inline; |
11 |
}
|
12 |
.menu li + li { |
13 |
margin-left: 35px; |
14 |
}
|
15 |
.menu li a { |
16 |
color: #999; |
17 |
text-decoration: none; |
18 |
}
|
Finally, open up the browser and refresh http://localhost:5000/ to see our newly added navigation links.
Conclusion
Over the course of this article, we built a simple web app with two, mostly static, pages. In doing so, we learned a workflow that can be used to create more complex websites with dynamic content. Flask is a simple, but powerful framework that enables you to efficiently build web apps. Go ahead—check it out!
This post has been updated with contributions from Esther Vaati. Esther is a software developer and writer for Envato Tuts+.
This content originally appeared on Envato Tuts+ Tutorials and was authored by Lalith Polepeddi
Lalith Polepeddi | Sciencx (2014-01-20T02:46:27+00:00) An Introduction to Python’s Flask Framework. Retrieved from https://www.scien.cx/2014/01/20/an-introduction-to-pythons-flask-framework/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.