Learning Roadmap - Flask
Learning Roadmap - Flask
This roadmap is designed to guide you through the essential concepts of Flask, a
lightweight Python web framework. We will cover the core components necessary to
build our network automation dashboard.
Before diving into Flask, it's important to understand what a web framework is and why
we use one. A web framework provides a standard way to build and deploy web
applications. It offers tools and libraries that simplify common web development tasks,
such as routing URLs, handling HTTP requests and responses, managing databases, and
rendering templates. This abstraction allows developers to focus on the unique logic of
their application rather than reinventing the wheel for every project.
Why Flask?
Flask is a micro-framework, meaning it aims to keep the core simple but extensible. It
doesn't impose a specific structure or require particular libraries, giving developers a lot
of flexibility. This makes it an excellent choice for smaller applications, APIs, and for
learning web development concepts without being overwhelmed by a large,
opinionated framework. For our network automation dashboard, Flask's simplicity will
allow us to quickly build a functional prototype and understand the underlying
mechanisms.
Key Concepts:
• WSGI (Web Server Gateway Interface): A specification that describes how a web
server communicates with web applications written in Python. Flask applications
are WSGI applications.
• Jinja2: A modern and designer-friendly templating language for Python. We will
use Jinja2 to create dynamic HTML pages for our dashboard.
• Werkzeug: A comprehensive WSGI utility library that Flask uses internally for
handling requests, responses, and routing.
Recommended Resources:
Virtual Environments
Virtual environments are crucial for Python development. They allow you to create
isolated environments for your projects, preventing conflicts between different project
dependencies. Each virtual environment can have its own set of installed packages,
independent of other projects or the global Python installation.
Steps:
1. Install Python: Ensure you have Python 3.x installed on your system. You
mentioned using Linux or WSL, which typically come with Python pre-installed or
make it easy to install.
2. Create a Virtual Environment: bash python3 -m venv venv This command
creates a directory named venv (you can choose any name) that contains a copy
of the Python interpreter and a pip installer.
3. Activate the Virtual Environment:
◦ On Linux/WSL: bash source venv/bin/activate Once activated, your terminal
prompt will usually show the name of the virtual environment (e.g., (venv) ),
indicating that you are working within it.
4. Install Flask: bash pip install Flask This command installs Flask within your active
virtual environment.
Recommended Resources:
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
app.run(debug=True)
• from flask import Flask : Imports the Flask class from the flask package.
• app = Flask(__name__) : Creates an instance of the Flask application. __name__ is a
special Python variable that gets the name of the current module. Flask uses this to
locate resources like templates and static files.
• @app.route('/') : This is a decorator that associates the hello_world function with
the URL route / . When a user navigates to the root URL of your application, this
function will be executed.
• def hello_world(): : The view function that handles requests to the / route. It
returns the string 'Hello, World!', which will be displayed in the user's browser.
• if __name__ == '__main__': : This block ensures that the app.run() method is only
called when the script is executed directly (not when imported as a module).
• app.run(debug=True) : Starts the Flask development server. debug=True enables
debug mode, which provides helpful error messages and automatically reloads the
server when code changes are detected.
Dynamic Routes
Flask allows you to create dynamic URLs by adding variable parts to your routes. These
variable parts are passed as arguments to your view functions.
app = Flask(__name__)
@app.route('/user/<username>')
def show_user_profile(username):
# show the user profile for that user
return f'User {username}'
@app.route('/post/<int:post_id>')
def show_post(post_id):
# show the post with the given id, the id is an integer
return f'Post {post_id}'
if __name__ == '__main__':
app.run(debug=True)
In this example:
Instead of hardcoding URLs in your templates or Python code, it's best practice to use
Flask's url_for() function. This function generates URLs for a given function name and
arguments. This makes your application more flexible and robust, as you can change
URL structures without updating every link.
app = Flask(__name__)
@app.route('/')
def index():
return 'Index Page'
@app.route('/login')
def login():
return 'Login Page'
@app.route('/user/<username>')
def profile(username):
return f'Profile for {username}'
with app.test_request_context():
print(url_for('index'))
print(url_for('login'))
print(url_for('login', next='/'))
print(url_for('profile', username='John Doe'))
Output:
/
/login
/login?next=/
/user/John%20Doe
url_for() takes the name of the view function as its first argument and any variable parts
of the URL as keyword arguments. It can also include query parameters.
Recommended Resources:
html
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>Hello, {{ name }}!</h1>
</body>
</html>
```python
from flask import Flask, render_template
app = Flask(name)
@app.route('/')
def index():
return render_template('index.html', title='Home Page', name='World')
if name == 'main':
app.run(debug=True)
```
Here:
Template Inheritance
Template inheritance is a powerful feature of Jinja2 that allows you to reuse common
HTML structures across multiple pages. You define a base template with common
elements (like headers, footers, and navigation) and then extend it in child templates.
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}My App{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<nav>
<a href="/">Home</a>
<a href="/devices">Devices</a>
<a href="/logs">Logs</a>
</nav>
<div class="content">
{% block content %}{% endblock %}
</div>
</body>
</html>
• {% block title %} and {% block content %} : These are Jinja2 blocks. Child
templates can override the content within these blocks.
• url_for('static', filename='style.css') : This is how you link to static files (like CSS,
JavaScript, images) in Flask. By default, Flask looks for static files in a folder named
static .
{% extends 'base.html' %}
{% block title %}Home{% endblock %}
{% block content %}
<h1>Welcome to the Network Automation Dashboard!</h1>
<p>This is the homepage content.</p>
{% endblock %}
Jinja2 also supports control structures like if statements and for loops, allowing for
dynamic content generation within your templates.
{% if user %}
<p>Hello, {{ user.name }}!</p>
{% else %}
<p>Hello, Guest!</p>
{% endif %}
<ul>
{% for device in devices %}
<li>{{ device.hostname }} - {{ device.ip_address }}</li>
{% endfor %}
</ul>
Recommended Resources:
Installation
```python
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Email
class LoginForm(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
password = PasswordField('Password', validators=[DataRequired()])
submit = SubmitField('Sign In')
class RegistrationForm(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
submit = SubmitField('Register')
```
```python
from flask import Flask, render_template, flash, redirect, url_for
from forms import LoginForm
app = Flask(name)
app.config['SECRET_KEY'] = 'a_very_secret_key_that_you_should_change'
if name == 'main':
app.run(debug=True)
```
```html
{% block content %}
Sign In
{{ form.hidden_tag() }}
{{ form.username.label }}
{{ form.username(size=32) }}
{% for error in form.username.errors %}
[{{ error }}]
{% endfor %}
{{ form.password.label }}
{{ form.password(size=32) }}
{% for error in form.password.errors %}
[{{ error }}]
{% endfor %}
{{ form.submit() }}
{% endblock %} ```
Recommended Resources:
What is an ORM?
An ORM allows you to interact with your database using Python objects instead of
writing raw SQL queries. This makes your code more Pythonic, readable, and less prone
to SQL injection vulnerabilities.
Installation
Basic Setup
```python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(name)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///site.db"
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
def __repr__(self):
return f"<User {self.username}>"
@app.route("/")
def index():
return "Hello, Database!"
if name == "main":
app.run(debug=True)
```
Adding Data
from app import db, User # Assuming your Flask app and User model are in app.py
Querying Data
# Get user by ID
user_by_id = User.query.get(1)
print(user_by_id.username)
Updating Data
user = User.query.filter_by(username=\'testuser\').first()
user.email = \'[email protected]\'
db.session.commit()
Deleting Data
user = User.query.filter_by(username=\'testuser\').first()
db.session.delete(user)
db.session.commit()
Recommended Resources:
Setup
1. Create a static folder: By default, Flask looks for static files in a folder named
static in the same directory as your application file.
2. Place your static files inside this folder. For example, static/css/style.css .
As seen in the template inheritance section, you link to static files using url_for() with
the special endpoint static :
References
[1] Flask Official Documentation. Available at: https://flask.palletsprojects.com/en/
latest/
[2] Grinberg, M. (n.d.). The Flask Mega-Tutorial. Available at: https://
blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world
[3] Python Documentation. (n.d.). venv — Creation of virtual environments. Available at:
https://docs.python.org/3/library/venv.html
[4] Flask Documentation. (n.d.). Routing. Available at: https://flask.palletsprojects.com/
en/latest/quickstart/#routing
[5] Jinja2 Documentation. Available at: https://jinja.palletsprojects.com/en/latest/
[6] Flask Documentation. (n.d.). Templating. Available at: https://
flask.palletsprojects.com/en/latest/tutorial/templates/
[7] Flask-WTF Documentation. Available at: https://flask-wtf.readthedocs.io/en/1.2.x/
[8] WTForms Documentation. Available at: https://wtforms.readthedocs.io/en/3.1.x/
[9] Flask-SQLAlchemy Documentation. Available at: https://flask-
sqlalchemy.palletsprojects.com/en/3.1.x/
[10] SQLAlchemy Documentation. Available at: https://docs.sqlalchemy.org/en/20/
[11] Flask Documentation. (n.d.). Static Files. Available at: https://
flask.palletsprojects.com/en/latest/quickstart/#static-files