Learning Goals
3 min- Install Flask; write a hello-world server.
- Define routes with
@app.route("/"). - Add path parameters (
/user/<name>). - Read query parameters; return JSON; return proper status codes.
Warm-Up · Hello, Web
5 minpip install flask
# app.py from flask import Flask app = Flask(__name__) @app.route("/") def home(): return "Hello, web!" if __name__ == "__main__": app.run(debug=True)
Run it:
$ python app.py * Running on http://127.0.0.1:5000/ * Debug mode: on
Open http://localhost:5000 in your browser. You just ran your first server.
A Flask app is just a Python file. The decorator @app.route maps a URL path to a function. Whatever the function returns becomes the HTTP response.
New Concept · Routes, Paths, Queries
14 minMultiple routes
@app.route("/") def home(): return "Home" @app.route("/about") def about(): return "About me" @app.route("/contact") def contact(): return "Email: me@example.com"
Path parameters
@app.route("/hello/<name>") def hello(name): return f"Hello, {name}!" # /hello/Aisyah → "Hello, Aisyah!" # Typed: @app.route("/square/<int:n>") def square(n): return f"{n} squared is {n*n}"
Converters: <int:n>, <float:x>, <path:p> (allows slashes).
Query parameters
from flask import request @app.route("/greet") def greet(): name = request.args.get("name", "stranger") times = int(request.args.get("times", 1)) return ("Hi " + name + "! ") * times # /greet?name=Aisyah×=3
JSON response
from flask import jsonify @app.route("/api/users") def users(): return jsonify([ {"id": 1, "name": "Aisyah"}, {"id": 2, "name": "Wei Jie"}, ])
Returning a dict directly also auto-JSONs in modern Flask: return {"hello": "world"}.
Status codes & tuples
@app.route("/missing") def missing(): return {"error": "not found"}, 404 @app.route("/created") def created(): return {"id": 42}, 201, {"X-Custom-Header": "yes"}
Worked Example · Mini-API + HTML Home
12 min# app.py — first real Flask app from flask import Flask, request, jsonify app = Flask(__name__) @app.route("/") def home(): return """ <h1>Welcome to PY-L4-38</h1> <ul> <li><a href="/hello/Aisyah">/hello/Aisyah</a></li> <li><a href="/square/12">/square/12</a></li> <li><a href="/greet?name=Mei×=3">/greet?name=Mei×=3</a></li> <li><a href="/api/products">/api/products</a></li> </ul> """ @app.route("/hello/<name>") def hello(name): return f"<h2>Hello, {name}!</h2>" @app.route("/square/<int:n>") def square(n): return f"<p>{n} squared is <strong>{n*n}</strong></p>" @app.route("/greet") def greet(): name = request.args.get("name", "stranger") times = int(request.args.get("times", 1)) return f"<p>{'Hi ' + name + '! ' * times}</p>" PRODUCTS = [ {"id": 1, "name": "Roti", "price": 1.50}, {"id": 2, "name": "Milo", "price": 3.00}, {"id": 3, "name": "Nasi", "price": 8.00}, ] @app.route("/api/products") def api_products(): return jsonify(PRODUCTS) @app.route("/api/products/<int:pid>") def api_product(pid): for p in PRODUCTS: if p["id"] == pid: return jsonify(p) return {"error": "not found"}, 404 if __name__ == "__main__": app.run(debug=True)
Visit in browser
http://localhost:5000/ → links list http://localhost:5000/hello/Mei → "Hello, Mei!" http://localhost:5000/square/12 → "12 squared is 144" http://localhost:5000/api/products → JSON array http://localhost:5000/api/products/99 → 404 + error JSON
Multi-line HTML strings get unreadable fast. Tomorrow we move to Jinja templates — Flask's built-in HTML system.
Try It Yourself
13 minAdd a route at /about returning your name and one sentence about you.
Add /fact/<int:n> that returns the factorial of n. Use math.factorial.
Load a CSV at startup into a list of dicts. Expose /api/items (list) and /api/items/<int:id> (one item or 404).
Hint
import csv with open("items.csv", newline="") as f: ITEMS = list(csv.DictReader(f)) @app.route("/api/items") def items(): return jsonify(ITEMS) @app.route("/api/items/<int:i>") def item(i): for r in ITEMS: if int(r["id"]) == i: return jsonify(r) return {"error": "not found"}, 404
Mini-Challenge · Multi-Tool API
8 minBuild five small JSON endpoints in one app:
/api/dice?n=2— roll n d6s, return list of integers./api/coin?n=3— flip n coins, return list of "H"/"T"./api/today— return today's date + weekday./api/temp?c=30— convert C to F./api/echo?msg=hi— echo the message.
Recap
3 minRoutes map URLs to functions. <name> in the path becomes a function argument. request.args holds query parameters. Return strings (HTML), dicts (JSON), or tuples (body, status, headers). Tomorrow we replace inline HTML with Jinja templates.
Vocabulary Card
- route
- A URL path that maps to a Python function.
- path parameter
- Variable section of the URL, e.g.,
/users/<name>. - query parameter
?key=valueafter the path. Accessed viarequest.args.- jsonify
- Convert a dict / list to a proper JSON response with the right Content-Type.
Homework
4 minBuild portfolio_api.py — a tiny "about me" API with /api/me, /api/projects, /api/skills endpoints returning JSON. Push it to a public GitHub repo with a README explaining how to run it.