Fall 2026
  • Discord
  • Gradescope
  • Syllabus

On this page

  • Start
  • The Visitor’s Menu
  • A Feed We Can Inspect
  • Saved Posts in the Feed
  • An Image and Shared Styles
  • A Visit Through the Board
  • Submit
  • Grading Rubric

Lab: FastAPI App

Due: Wednesday, December 9 at 11:59pm (one week after it is assigned) · Worth: 8 points

Build a message board where visitors can read saved posts and follow a shared menu. Use twitter-clone, your final-project repository; there is no starter. Authentication and creating messages come in the final project. This lab requires their pages and navigation, plus a working database feed.

Start

Create and clone an empty twitter-clone repository if you do not already have one. In this repository, set up its Python environment. Create requirements.txt with these four lines:

fastapi
uvicorn
jinja2
python-multipart

Install them:

$ python -m pip install -r requirements.txt

Keep .venv/, __pycache__/, and .env in .gitignore. Work from the repository root with app.py, templates/, and static/. Copy db_create.py and schema.sql from the SQL reading’s local database checkpoint. They seed the first database and preserve it on later runs. Use the backend reading for the FastAPI and template patterns.

The Visitor’s Menu

Create a menu linking these five routes:

Each route needs its own HTML template extending base.html. Put the shared menu and site <h1> in base.html, and each page’s <h2> in its own template.

A Feed We Can Inspect

The / route must open a connection to a database created by db_create.py and display all of the messages, sorted with the most recent message at the top. For each message, you must display:

First pass a hard-coded list of message dictionaries to the home template and render it with a Jinja2 loop. Each dictionary needs the four fields above. The Jinja2 primer covers lists, dictionaries, and loops.

Saved Posts in the Feed

Replace the fake data with a SQL join of messages and users, as in the SQL reading. Include all ages: remove the reading example’s adults-only WHERE clause. Use ? placeholders for any user-supplied values.

Run python db_create.py to create the database before starting the app with python -m uvicorn app:app --reload. Open http://127.0.0.1:8000 and leave that terminal running while you test each route. If you use a different Python filename, replace the first app in app:app with that filename without .py.

Check that every saved message appears with its author’s name and age, its timestamp, and newest-first ordering.

An Image and Shared Styles

Mount the static/ directory using the FastAPI static-files guide.

For a missing asset, open its /static/... URL directly and compare its spelling and capitalization with the committed filename. Start the server from the repository root so it can find the directory. Choose a name and appearance for your board; extra visual customization in the final project is ungraded.

A Visit Through the Board

Follow the menu through all five routes: each should have its own <h2> beneath the shared <h1> and use the shared stylesheet. On /, check the image and database feed.

Submit

Create and check out a lab-submission branch containing the app, db_create.py, schema.sql, requirements.txt, .gitignore, templates/, and static/. Commit and sync it, then submit twitter-clone and that branch through Gradescope’s GitHub option. No screenshot is required; the first lab has the submission steps.

Before returning to final-project work, copy the completed lab into your main branch:

$ git switch main
$ git merge lab-submission

Use master if that is your default branch’s name. If git switch main reports that the branch does not exist, create it from your current lab-submission commit with git switch -c main; no merge is needed in that case. After submitting, keep lab-submission unchanged and make later commits on your main branch. Your final project will lose points if the lab-submission branch gets updated after you submit it.

Grading Rubric

Gradescope checks each item separately and adds the points earned.

Total: 8 points.