Flask: building web apps with Python
Learning objectives
By the end of this guide you will be able to:
- understand how a web app works and the role of Flask;
- create a local server with routes and associated functions;
- handle
GETandPOSTrequests; - use HTML templates with Jinja2;
- manage forms, cookies and sessions;
- correctly structure a mini Flask application.
What is Flask
Flask is a micro web framework for Python: lightweight, flexible and ideal for learning how web applications work. It imposes no rigid structure and lets you add only what you need.
Note: Flask is built on two main components:
- Werkzeug – handles HTTP requests and responses;
- Jinja2 – a template engine for generating dynamic HTML pages.
Installation and first example
Install Flask with:
pip install flask
Create a file app.py:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "Hello from the Flask server!"
if __name__ == "__main__":
app.run(debug=True)
Run with: python app.py → open your browser at http://127.0.0.1:5000
Routes and HTTP methods
Every route is a Python function associated with a URL.
@app.route("/info")
def info():
return "<h2>Server information</h2>"
@app.route("/greet/<name>")
def greet(name):
return f"Hello, {name}!"
You can specify HTTP methods:
@app.route("/data", methods=["GET", "POST"])
def data():
if request.method == "POST":
return "You submitted data!"
else:
return "Data query page"
HTML templates with Jinja2
Create a templates/ folder and add an index.html file:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Welcome</title></head>
<body>
<h1>Hello, {{ name }}</h1>
</body>
</html>
In the Python file:
from flask import render_template
@app.route("/page/<name>")
def page(name):
return render_template("index.html", name=name)
Forms and POST requests
from flask import request
@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST":
user = request.form["user"]
return f"Welcome, {user}!"
return '''
<form method="POST">
Username: <input name="user">
<input type="submit" value="Login">
</form>
'''
Redirects and flash messages
You can redirect the user and display temporary messages:
from flask import redirect, url_for, flash
app.secret_key = "secret_key"
@app.route("/start")
def start():
flash("Login successful!")
return redirect(url_for("home"))
In the template:
{% with messages = get_flashed_messages() %}
{% for msg in messages %}
<p style="color:green">{{ msg }}</p>
{% endfor %}
{% endwith %}
Static files and project structure
Flask automatically looks for static files in the static/ folder (e.g. images, CSS, JavaScript).
project/
|-- app.py
|-- templates/
| |-- index.html
|-- static/
|-- style.css
Sessions and Cookies
Sessions allow you to store information server-side across multiple requests.
from flask import session
app.secret_key = "supersecret"
@app.route("/set/<user>")
def set_user(user):
session["user"] = user
return f"Session set for {user}"
@app.route("/who")
def who():
if "user" in session:
return f"Active user: {session['user']}"
return "No active session"
Final mini-project: login and greeting
from flask import Flask, render_template, request, redirect, url_for, session
app = Flask(__name__)
app.secret_key = "flaskpillolona"
@app.route("/", methods=["GET", "POST"])
def login():
if request.method == "POST":
name = request.form["name"]
session["user"] = name
return redirect(url_for("home"))
return render_template("login.html")
@app.route("/home")
def home():
if "user" not in session:
return redirect(url_for("login"))
return render_template("home.html", name=session["user"])
@app.route("/logout")
def logout():
session.pop("user", None)
return redirect(url_for("login"))
login.html:
<form method="POST">
<input name="name" placeholder="Username">
<button type="submit">Login</button>
</form>
home.html:
<h2>Hello {{ name }}!</h2>
<a href="{{ url_for('logout') }}">Logout</a>
POST requests with JSON data and Query Parameters
Besides HTML forms, Flask can receive and send data as JSON or via URL parameters.
Receiving JSON data
When a client sends a request with Content-Type: application/json, Flask lets you read the body via request.get_json().
from flask import jsonify
@app.route("/api/data", methods=["POST"])
def receive_json():
data = request.get_json()
name = data.get("name")
grade = data.get("grade")
return jsonify({
"message": f"Data received for {name}",
"average": (grade + 10) / 2
})
Note: You can test this from the terminal with:
curl -X POST -H "Content-Type: application/json" \ -d '{"name": "Luca", "grade": 8}' \ http://127.0.0.1:5000/api/data
Query string parameters
Parameters in the URL query string (e.g. ?user=Mario&score=90) are read via request.args.
@app.route("/score")
def score():
user = request.args.get("user", "Anonymous")
points = request.args.get("score", 0, type=int)
return f"{user} scored {points} points!"
Note: Example:
http://127.0.0.1:5000/score?user=Luca&score=95
Server-side Cookie Management
Cookies allow you to store small pieces of information in the user’s browser.
Setting a cookie
from flask import make_response
@app.route("/set_cookie")
def set_cookie():
resp = make_response("Cookie set!")
resp.set_cookie("user", "Julia", max_age=60*60*24) # valid 1 day
return resp
Reading a cookie
@app.route("/get_cookie")
def get_cookie():
user = request.cookies.get("user")
if user:
return f"Welcome back, {user}!"
return "No cookie found."
Deleting a cookie
@app.route("/del_cookie")
def del_cookie():
resp = make_response("Cookie deleted.")
resp.delete_cookie("user")
return resp
Note: Cookies are managed by the browser and sent automatically with every request to the same domain, making it possible to maintain sessions or user preferences.
In brief: Flask is a powerful and accessible tool for building dynamic web apps with Python. With just a few files you can create APIs, dashboards and complete applications, integrating HTML, CSS and databases.
EC