Create venv
Create a new folder
1
2
| $ mkdir demo_flask_board
$ cd demo_flask_board
|
Create a venv environment
On Windows
1
2
| python -m venv venv
.\venv\Scripts\activate
|
On Linux
1
2
3
| $ python3 -m venv venv
$ source venv/bin/activate
(venv) $
|
Example:
1
2
3
| gus@ubuntu-vm:~/projects/demo_flask_board$ python3 -m venv venv
gus@ubuntu-vm:~/projects/demo_flask_board$ source venv/bin/activate
(venv) gus@ubuntu-vm:~/projects/demo_flask_board$
|
Install Python Flask using pip
1
| python3 -m pip install Flask
|
Output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| (venv) gus@ubuntu-vm:~/projects/demo_flask_board$ python3 -m pip install Flask
Collecting Flask
Downloading flask-3.0.3-py3-none-any.whl (101 kB)
|████████████████████████████████| 101 kB 4.9 MB/s
Collecting itsdangerous>=2.1.2
Downloading itsdangerous-2.2.0-py3-none-any.whl (16 kB)
Collecting Jinja2>=3.1.2
Downloading jinja2-3.1.4-py3-none-any.whl (133 kB)
|████████████████████████████████| 133 kB 17.2 MB/s
Collecting click>=8.1.3
Downloading click-8.1.7-py3-none-any.whl (97 kB)
|████████████████████████████████| 97 kB 9.2 MB/s
Collecting importlib-metadata>=3.6.0; python_version < "3.10"
Downloading importlib_metadata-8.0.0-py3-none-any.whl (24 kB)
Collecting blinker>=1.6.2
Downloading blinker-1.8.2-py3-none-any.whl (9.5 kB)
Collecting Werkzeug>=3.0.0
Downloading werkzeug-3.0.3-py3-none-any.whl (227 kB)
|████████████████████████████████| 227 kB 8.1 MB/s
Collecting MarkupSafe>=2.0
Downloading MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (26 kB)
Collecting zipp>=0.5
Downloading zipp-3.19.2-py3-none-any.whl (9.0 kB)
Installing collected packages: itsdangerous, MarkupSafe, Jinja2, click, zipp, importlib-metadata, blinker, Werkzeug, Flask
Successfully installed Flask-3.0.3 Jinja2-3.1.4 MarkupSafe-2.1.5 Werkzeug-3.0.3 blinker-1.8.2 click-8.1.7 importlib-metadata-8.0.0 itsdangerous-2.2.0 zipp-3.19.2
(venv) gus@ubuntu-vm:~/projects/demo_flask_board$
|
Run Flask
Create file app.py
1
2
3
4
5
6
7
8
9
10
| from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "Hello, World!"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True)
|
Run with:
Output
1
2
3
4
5
6
7
8
9
10
11
| (venv) gus@ubuntu-vm:~/projects/demo_flask_board$ python app.py
* Serving Flask app 'app'
* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:8000
* Running on http://192.168.0.42:8000
Press CTRL+C to quit
* Restarting with stat
* Debugger is active!
* Debugger PIN: 362-633-512
|
Run Flask (using Blueprints)
1
2
| (venv) $ mkdir board
(venv) $ mv app.py board/__init__.py
|
The result is that board/__init__.py
is exactly the same code as app.py
from the previous section.
Directory structure:
1
2
3
4
| demo_flask_board/
│
└── board/
└── __init__.py
|
Run with:
1
| (venv) $ python -m flask --app board run --port 8000 --debug
|
Output
1
2
3
4
5
6
7
8
9
| (venv) gus@ubuntu-vm:~/projects/demo_flask_board$ python -m flask --app board run --port 8000 --debug
* Serving Flask app 'board'
* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:8000
Press CTRL+C to quit
* Restarting with stat
* Debugger is active!
* Debugger PIN: 848-111-764
|
Application factory design pattern
With an application factory, the project’s structure becomes more organized. It encourages you to separate different parts of your application, like routes, configurations, and initializations, into different files later on. This encourages a cleaner and more maintainable codebase.
board/__init__.py
1
2
3
4
5
6
| from flask import Flask
def create_app():
app = Flask(__name__)
return app
|
Using Blueprints
Blueprints are modules that contain related views that can be conveniently imported in __init__.py
. For example, you’ll have a blueprint that stores the main pages of your project.
board/pages.py
1
2
3
4
5
6
7
8
9
10
11
| from flask import Blueprint
bp = Blueprint("pages", __name__)
@bp.route("/")
def home():
return "Hello, Home!"
@bp.route("/about")
def about():
return "Hello, About!"
|
board/__init__.py
1
2
3
4
5
6
7
8
9
| from flask import Flask
from board import pages
def create_app():
app = Flask(__name__)
app.register_blueprint(pages.bp)
return app
|
Templates
Project structure:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| (venv) gus@ubuntu-vm:~/projects/demo_flask_board$ tree -I venv
.
└── board
├── __init__.py
├── pages.py
├── static
│ └── styles.css
└── templates
├── base.html
├── _navigation.html
└── pages
├── about.html
└── home.html
(venv) gus@ubuntu-vm:~/projects/demo_flask_board$
|
board/static/styles.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| * {
box-sizing: border-box;
}
body {
font-family: sans-serif;
font-size: 20px;
margin: 0 auto;
text-align: center;
}
a,
a:visited {
color: #007bff;
}
a:hover {
color: #0056b3;
}
nav ul {
list-style-type: none;
padding: 0;
}
nav ul li {
display: inline;
margin: 0 5px;
}
main {
width: 80%;
margin: 0 auto;
}
|
board/templates/_navigation.html
1
2
3
4
5
6
| <nav>
<ul>
<li><a href="{{ url_for('pages.home') }}">Home</a></li>
<li><a href="{{ url_for('pages.about') }}">About</a></li>
</ul>
</nav>
|
board/templates/base.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| <!DOCTYPE html>
<html lang="en">
<head>
<title>Message Board - {% block title %}{% endblock title %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
</head>
<body>
<h1>Message Board</h1>
{% include("_navigation.html") %}
<section>
<header>
{% block header %}{% endblock header %}
</header>
<main>
{% block content %}<p>No messages.</p>{% endblock content %}
</main>
</section>
</body>
</html>
|
board/templates/pages/home.html
1
2
3
4
5
6
7
8
9
10
11
| {% extends 'base.html' %}
{% block header %}
<h2>{% block title %}Home{% endblock title %}</h2>
{% endblock header %}
{% block content %}
<p>
Learn more about this project by visiting the <a href="{{ url_for('pages.about') }}">About page</a>.
</p>
{% endblock content %}
|
board/templates/pages/about.html
1
2
3
4
5
6
7
8
9
| {% extends 'base.html' %}
{% block header %}
<h2>{% block title %}About{% endblock title %}</h2>
{% endblock header %}
{% block content %}
<p>This is a message board for friendly messages.</p>
{% endblock content %}
|
board/pages.py
1
2
3
4
5
6
7
8
9
10
11
| from flask import Blueprint, render_template
bp = Blueprint("pages", __name__)
@bp.route("/")
def home():
return render_template("pages/home.html")
@bp.route("/about")
def about():
return render_template("pages/about.html")
|
Run with:
1
| python -m flask --app board run --port 8000 --debug
|
Output
1
2
3
4
5
6
7
8
9
| (venv) gus@ubuntu-vm:~/projects/demo_flask_board$ python -m flask --app board run --port 8000 --debug
* Serving Flask app 'board'
* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:8000
Press CTRL+C to quit
* Restarting with stat
* Debugger is active!
* Debugger PIN: 848-111-764
|
References
- https://realpython.com/flask-project/