← Teacher guides

Teacher guide: Web apps with Flask

Your own HTML pages with Python behind them: routes, pages built from data, forms, saving to a file and JSON, ending with the same API in FastAPI.

Open the student course

Each lesson works two ways. Students can work through the online tutorial at their own pace (it checks their answers and saves their progress in their browser), or you can teach it to the whole class from the slides, then send students into the tutorial for the Modify and Make steps.

Every lesson guide has plain-language notes, the answers to every check, a solution for every task, and slides and a worksheet for Waypoints Prepare. These guide pages are not linked from student pages, but they are not secret either: keep printed Teacher editions for answers you do not want students to find.

Whole-course cheat sheet: Open to print (every command, grouped by unit: a handout for the final challenge)

Pages from Python

Routes join addresses to functions; templates build pages from data.

Pages from Python in 5 minutes (read before teaching this unit)

The idea in plain words

A web app makes its pages with code. The browser asks for an address (/about); a program on the server decides what to send back. In Flask, a route joins an address to a function: @app.route("/about") above def about():. Whatever the function returns, usually HTML text, is the page. An address with no route gets the standard 404 Not Found.

A template is HTML with gaps, filled in from data: {{ p["name"] }} shows a value and {% for p in players %} ... {% endfor %} repeats a part for each item. render_template_string(PAGE, players=players) fills it in; the template sees only what is passed to it. A route can have a part that changes: /player/<name> passes whatever is in that place to the function.

Why programmers use them

  • Pages that change: the latest results, a page for every player, answers to a search.
  • One template, any amount of data: 4 players or 400 need the same code.

An everyday picture, and where it breaks

A restaurant: the address is the order, the route is the menu line that says which cook makes it, and the function is the cook. A template is a form letter with blanks. It breaks because the "cook" answers instantly and identically every time, and forgets everything between orders unless it writes it down (Lesson 4).

Try it yourself (5 minutes)

  1. Run Lesson 1's app and visit /about, then /missing.
  2. In Lesson 2, add a fifth player to the list and run again: a new row and a new page appear.
  3. Visit /player/Zoe and read the reply.

Questions students ask

  • Is this a real website? In the playground it runs only in your browser. On a computer, python app.py serves it at http://127.0.0.1:5000, and hosting it for others needs a server (a teacher job).
  • Why single quotes inside the HTML? The HTML is inside a Python string in double quotes, so attributes use single quotes.
  • Where do templates go on a computer? In a templates folder, loaded with render_template("club.html"). The {{ }} and {% %} work the same.

Cheat sheet: Open to print (A4, with a picture of what each command draws) · Markdown

Forms and saving

Take answers from a form, check them, and save them to a file so they last.

Forms and saving in 5 minutes (read before teaching this unit)

The idea in plain words

Forms. <form method="post" action="/join"> sends the form to /join when the button is pressed. Only boxes with a name attribute are sent, under that name. A route with methods=["POST"] reads them: request.form["name"]. After changing the data, redirect("/") sends the browser back to a page that shows the change. The server checks what it gets (a blank name, a repeat), because anyone can send anything to an address.

Saving. Variables last only while the app runs. Data that must last goes in a file: each sign-up adds a row to members.csv with open(..., "a") and csv.writer, and every page reads the file with csv.DictReader. "a" adds to the end; "w" empties the file first. Changing one row means reading every row, changing it, and writing them all back with "w", header first.

Why programmers use them

  • Forms are how people give a web app information: sign-ups, searches, orders, comments.
  • Storage is what makes an app useful tomorrow. Small apps use files; busy ones use a database, which copes with many people changing data at once.

An everyday picture, and where it breaks

A sign-up sheet on a clipboard: the form is the sheet, the route is the person who reads it and copies each name into the club book (the file). It breaks because the person never guesses: a box without a name is invisible to them, and they will happily copy a blank line unless told to check.

Try it yourself (5 minutes)

  1. Run Lesson 3's app, join twice, then press Run: the new members are gone.
  2. Run Lesson 4's app, join, press Run and reload: the member is still there. Open members.csv in the Files tab.
  3. Remove name="name" from the input in Lesson 3 and press Join: 400 Bad Request.

Questions students ask

  • What is 400, 404, 405, 500? Status codes: 400 the request was wrong (a missing box), 404 no such page, 405 the route does not accept POST, 500 the code crashed.
  • Why redirect after a form? So the page shows the result, and reloading it does not send the form again.
  • Where is members.csv? In this browser, for this course (the Files tab). On a computer, next to app.py.

Cheat sheet: Open to print (A4, with a picture of what each command draws) · Markdown

APIs

Send data as JSON for other programs, then the same API in FastAPI.

APIs in 5 minutes (read before teaching this unit)

The idea in plain words

A page is for people; an API is for programs. An API route sends data, usually as JSON: in Flask, a route that returns a dictionary sends it as JSON, which almost any language reads straight back into a dictionary or list. A query string (/api/members?name=ad) asks a question; Flask reads it with request.args.get("name", "").

FastAPI (the optional last lesson) builds APIs with types: def next_year(age: int): makes FastAPI read age from the address, turn it into a whole number, and reply 422 with an explanation when it cannot, before your code runs. Without the type, the value would be text. Routes are @api.get("/address"), the changing part of an address is {group}, and uvicorn.run(api) starts it.

Why programmers use them

  • Apps talk to each other through APIs: weather, maps, music and school systems all share data this way.
  • Checked inputs stop bad data before it reaches your code; FastAPI also writes the API's documentation from the types.

An everyday picture, and where it breaks

A library's catalogue terminal: you ask a question in a fixed form and get a printed list back, not a decorated poster. FastAPI's types are the librarian who refuses "twelve" in a box marked "number". It breaks because an API answers anyone who asks, so what it shares must be chosen carefully.

Try it yourself (5 minutes)

  1. Run Lesson 5's app and open /api/members/Players.
  2. Try /api/members/Nobody: an empty answer, not an error.
  3. In Lesson 6, try /next-year?age=twelve and read the 422 reply.

Questions students ask

  • Why not just use the web page? A program would have to pick the data out of the HTML; JSON gives it names and values directly.
  • Flask or FastAPI? Flask for pages and forms, FastAPI for APIs; both can do either.
  • Is the data public? Anyone with the address can read an API, so real APIs share only what is safe and protect the rest with logins or keys.

Cheat sheet: Open to print (A4, with a picture of what each command draws) · Markdown