TDM 40200: Project 9 — 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 eighth 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
Dataset(s)
The following questions will use the following dataset(s):
-
/anvil/projects/tdm/data/movies_and_tv/imdb.db
Questions
Question 1
Let’s start this project with a fresh slate: fresh frontend and backend to work on.
mv $SCRATCH/imdb $SCRATCH/imdb.bak3
mkdir $SCRATCH/imdb
cp -a /anvil/projects/tdm/etc/project08/* $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.
-
Code used to solve this problem.
-
Output from running the code.
Question 2
You may notice a few changes to the frontend and backend. They are largely just changes so that you can add a title, select the genres for the title, and add the number of votes and rating as well. If you peek in the backend, you will see that this is accomplished using 2 database inserts. One insert handles inserting the data that normally lives in the titles
table, and the other handles inserting the rating
, votes
, and title_id
in the ratings
table. Its not any harder than the previous project, however, it added unnecessary complexity that we didn’t want you to worry about for your very first project dealing with forms.
For this project, we are going to implement two new pages:
Ultimately, these two pages will display forms with the current data for the given person with person_id
or title with title_id
, and allow the user to replace any information with new updated information. Upon clicking the buttons, the data will be updated in the database. Pretty straightforward! This is all common behavior, and the update part of CRUD (create, read, update, and delete).
First thing is first, start by creating two new templates: update_person.html
and update_title.html
. For now, these can be copy/pasted from the create_person.html
and create_title.html
templates — we will make progressive modifications to these templates as we go.
Next, create two new endpoints in endpoints.py
: 1 to handle displaying the update_person.html
template (using a function called update_person
), and 1 to handle displaying the update_title.html
template (using a function called update_title
).
Finish this question by taking two screenshots of the two new pages, and including them in your jupyter notebook.
Please make sure that the URL is included in the screenshots.
-
Code used to solve this problem.
-
Output from running the code.
Question 3
Well, these pages are pretty boring, and so far, not really helpful at all! We can’t really see the data we are wanting to modify! Who is person nm0430107
? What is title tt1825683
? It is important to both have a form to update data and to be able to see the data we are wanting to update!
The way to accomplish this is by using the value
attribute of the various input
tags in the update_title.html
and update_person.html
templates. For example, given the following input
tag:
<input type="text" name="primary_name" id="primary_name" value="John Smith">
The resulting form will look like a regular "text" input
field, but it will already have the text "John Smith" inside of it!
Update the update_person
and update_title
functions in endpoints.py
to make a request (using the httpx
library, just like we do in the get_title
function in endpoints.py
) and get the current information for the person or title of interest. Pass this data to the update_person.html
or update_title.html
templates, and use the value
attribute to display the current data in the form.
Finish this question by taking two screenshots of the two new pages, and including them in your jupyter notebook.
Please make sure that the URL is included in the screenshots.
A tip for handling the checkboxes. In your
This will do two primary things. Let you access each checkbox and check it in the template by doing something like:
In addition, it will convert the "-" in "sci-fi" to an underscore, so it can be accessed in the template. |
-
Code used to solve this problem.
-
Output from running the code.
Question 4
Okay, the final step is to actually update the data in the database upon a form submission. In order to make this work, you must update your two templates so that the method
attribute is post
, and the action
attribute is /people/{person_id}/update
or /titles/{title_id}/update
endpoints of your backend.
Next, you must update your backend, so those endpoints take the form data and actually update the data in the database. To do this, you will need to create two new endpoints in api.py
that take the form data and update the values in the database. Please note, you will also need to create two new queries in queries.sql
.
Use both of your new "update" forms to update a known title and actor. Take two screenshots of the pages that appear after submitting the forms. Include these screenshots in your jupyter notebook.
-
Code used to solve this problem.
-
Output from running the code.
Question 5
Finally, prove that your updates were successful by taking two screenshots of the following pages, now that you’ve updated the data in the database.
-
Code used to solve this problem.
-
Output from running the code.
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. |