TDM 40200: Project 10 — 2023

Motivation: Dashboards are everywhere — many of our corporate partners' projects are to build dashboards (or dashboard variants)! Dashboards are used to interactively visualize some set of data. Dashboards can be used to display, add, remove, filter, or complete some customized operation to data. Ultimately, a dashboard is really a website focused on displaying data. Dashboards are so popular, there are entire frameworks designed around making them with less effort, faster. Two of the more popular examples of such frameworks are shiny (in R) and dash (in Python). While these tools are incredibly useful, it can be very beneficial to take a step back and build a dashboard (or website) from scratch (we are going to utilize many powerfuly packages and tools that make this far from "scratch", but it will still be more from scratch than those dashboard frameworks).

Context: This is the ninth in a series of projects focused around slowly building a dashboard. Students will have the opportunity to: create a backend (API) using fastapi, connect the backend to a database using aiosql, use the jinja2 templating engine to create a frontend, use htmx to add "reactivity" to the frontend, create and use forms to insert data into the database, containerize the application so it can be deployed anywhere, and deploy the application to a cloud provider. Each week the project will build on the previous week, however, each week will be self-contained. This means that you can complete the project in any order, and if you miss a week, you can still complete the following project using the provided starting point.

Scope: Python, dashboards

Learning Objectives
  • Continue to develop skills and techniques using fastapi to build a backend.

  • Learn how to use pydantic for data validation and type hints.

  • Learn how fastapi and pydantic work together to create endpoints that validate data and return typed responses.

  • Create a directory structure to assemble a fastapi backend.

  • Use fastapi and jinja2 to build a frontend.

  • Use fastapi and html to create forms to submit data to the database.

  • Use htmx to add "reactivity" to the frontend.

Make sure to read about, and use the template found here, and the important information about projects submissions here.

Dataset(s)

The following questions will use the following dataset(s):

  • /anvil/projects/tdm/data/movies_and_tv/imdb.db

Questions

Part 1

Let’s start this project with a fresh slate: fresh frontend and backend to work on.

mv $SCRATCH/imdb $SCRATCH/imdb.bak4
mkdir $SCRATCH/imdb
cp -a /anvil/projects/tdm/etc/project09/* $SCRATCH/imdb
cp /anvil/projects/tdm/data/movies_and_tv/imdb.db $SCRATCH/imdb/backend/api/

Then, to run the API, first load up our Python environment.

module use /anvil/projects/tdm/opt/core
module load tdm
module load python/f2022-s2023

Next, find an unused port to run the API on.

find_port # 7777, for example

Then, run the API using the port from the previous step, in our case, 7777.

cd $SCRATCH/imdb
python3 -m uvicorn backend.api.api:app --reload --port 7777

In addition, open another terminal to run the frontend using another port, in our case, 8888.

cd $SCRATCH/imdb
python3 -m uvicorn frontend.endpoints:app --reload --port 8888

You can visit the following links to see the barebones pages.

This is all you need to do for this question — just make sure those pages load up correctly.

Items to submit
  • Code used to solve this problem.

  • Output from running the code.

Part 2

The goal of this project is straightforward. Use htmx and make the modifications needed in order to update the following page so that it behaves like this htmx example.

Make the modifications needed so you can see the following. Of course, if you added your own custom CSS, that is perfectly fine, the behavior is what is critical.

Goal results
Figure 1. Goal results

To make a request and pass along the form data, you can use the following code:

async with httpx.AsyncClient() as client:
    resp = await client.post(f'{URL}', data=form_data)

Where form_data is a dict of key/value pairs.

This effectively transforms this part of the web app into a SPA (single page app) — you will notice that in the example, the URL does not change.

You don’t need to modify the backend at all — this project is all about the frontend.

Make sure that if you update an actor that is not yet dead, that you don’t leave "None" when updating the death date — this will throw an error since "None" is not a valid number. Just put in a number like 2050 or 2100.

You’ll ultimately just need to modify: people.html, update_person.html, and endpoints.py.

You’ll ultimately just need to add a single endpoint to endpoints.py.

Items to submit
  • Code used to solve this problem: the templates you updated, and endpoints.py.

  • GIF or video demonstrating the behavior of the web app — just like the example gif, but using a different actor. Be sure to include the entire screen, including the URL bar.

Please make sure to double check that your submission is complete, and contains all of your code and output before submitting. If you are on a spotty internet connection, it is recommended to download your submission after submitting it to make sure what you think you submitted, was what you actually submitted.

In addition, please review our submission guidelines before submitting your project.