Skip to content

Lab Exercise 7 (Superhero Catalog)

Overview

For this Lab Exercise, you will be making a web-based superhero info displayer using HTML and PyScript.

You will be working with the superhero-api, which provides data about superheroes across multiple universes (e.g. Marvel, DC).

For this lab exercise, you will be using the following URL to interact with superhero-api:

https://akabab.github.io/superhero-api/api

or the cached CDN version (faster):

https://cdn.jsdelivr.net/gh/akabab/superhero-api@0.3.0/api

The full API documentation can be found at https://akabab.github.io/superhero-api/api/.

Ensure that you use either of the two URLs for all parts of the exercise.

Warning

For this lab exercise, we will be treating the URL above as the root. Subsequent references to the API will no longer include the root, just the relevant endpoint (e.g., /id/{id}.json refers to https://akabab.github.io/superhero-api/api/id/{id}.json).

Info

You are expected to import (and use) the following:

You will not be allowed to modify index.html.

Scoring

This lab exercise will be scored in phases. You can get \(0/20/50/80/100 \%\) of the points in a phase depending on how far/close you are from meeting the phase's requirements. You must get \(\ge 80 \%\) of the points in each of the previous phases to get nonzero points for a certain phase.

This lab will be scored over \(100\) 🔴. Note that the points indicated beside each section are cumulative.

Note

For all phases, running python3 -m http.server then opening localhost:8000 should show a page exhibiting the expected behavior (assuming port 8000 is not already in use).

Indicate the farthest phase you (think you) got in a README.md file.

One ID, One Superhero (30 🔴 + 5 ❤️)

For this phase, you will be querying superhero-api using a text input and a button.

A user should input the id of the superhero they want to get the information of using the text input. When the button is clicked, the user should then be able to see the following information about the superhero they queried:

  • name (str),
  • gender (str | None),
  • race (str | None),
  • height (int, in cm), and
  • weight (int, in kg).

This information must be shown as a Python dictionary in a code block, using the pre HTML tag.

Info

Making a query to /id/{id}.json returns an object with the following structure:

{
  "id": ...,
  "name": ...,
  "appearance": {
    "gender": ...,
    "race": ...,
    "height": [
      "6'8",
      "... cm"
    ],
    "weight": [
      "... lb",
      "... kg"
    ],
    "eyeColor": "...",
    "hairColor": "..."
  },
}

Note that this isn't the entire structure of the returned object; only the relevant parts are shown here.

Info

You can pretty-print a Python dictionary by using json.dumps:

import json

json.dumps(object, indent=4)

Here, indent indicates the indentation level (in spaces) of the pretty-printed dictionary.

  • A text input element and a button element exist.
  • The relevant superhero information is shown when the button is pressed.
  • The text input is case-insensitive.

One ID, One Superhero++ (50 🔴 + 10 ❤️)

Let's present the superhero's information better! You must use the following tags to show information about the superhero:

  • an <img> tag for the superhero's (use the small-sized image sm links you obtain from superhero-api),
  • an <h1> tag for the superhero's name,
  • <code> tag(s) for the superhero's gender and race, separated by the | character, and
  • <p> tags for the superhero's height (in meters) and weight (in kilograms).

Note that the gender and race information could be null in JSON, or None when converted to Python. Display the string "None" for null values.

Ensure that it is easy to distinguish different parts of the information.

Info

The object obtained by making a query to /id/{id}.json also has the following field(s):

{
    "images": {
      "xs": "...",
      "sm": "...",
      "md": "...",
      "lg": "..."
    }
}

Note that the recommended link to use is for the small-sized image sm found in the images key; but you may use any of the image links.

  • The right HTML tags exist, and they show the correct information.

Human Superheroes (80 🔴 + 15 ❤️)

Let w be the text in the input field. In Phases 1 and 2, you only considered the superhero id; in this phase, you'll consider all Human superheroes whose name starts with w (case-insensitive)!

When the submit button is pressed, show the same information by using the same HTML tags for each superhero whose name starts with the input. Note that all names start with the empty string.

If you will be showing multiple superheroes, show them in increasing order of id.

You must get the information of all relevant Human superheroes concurrently.

Info

The /all.json endpoint obtains the data for all the superheroes available in the API.

Info

The styles display: grid; and grid-template-columns: auto auto ... auto; make an element have \(c\) columns, where \(c\) is the number of autos. For this phase, you are advised to set \(c\) to 3 or 4 for best (visual) results.

  • The search does not need to contain a full superhero name to work.
  • All information for all relevant superheroes is displayed properly.
  • All relevant superheroes are displayed concurrently.
  • The superheroes are displayed in increasing id number.

All the Superheroes (100 🔴 + 20 ❤️)

For the final phase, allow the user to decide which subset of races to choose from when finding all superhero whose names start with the input.

There should be a select element with the multiple attribute containing the options for races.

The unique races available in superhero-api are:

"Alien"
"Alpha"
"Amazon"
"Android"
"Animal"
"Asgardian"
"Atlantean"
"Bizarro"
"Black Racer"
"Bolovaxian"
"Clone"
"Cosmic Entity"
"Cyborg"
"Czarnian"
"Dathomirian Zabrak"
"Demi-God"
"Demon"
"Eternal"
"Flora Colossus"
"Frost Giant"
"God / Eternal"
"Gorilla"
"Gungan"
"Human / Altered"
"Human / Clone"
"Human / Cosmic"
"Human / Radiation"
"Human"
"Human-Kree"
"Human-Spartoi"
"Human-Vulcan"
"Human-Vuldarian"
"Icthyo Sapien"
"Inhuman"
"Kaiju"
"Kakarantharaian"
"Korugaran"
"Kryptonian"
"Luphomoid"
"Maiar"
"Martian"
"Metahuman"
"Mutant / Clone"
"Mutant"
"New God"
"Neyaphem"
"Parademon"
"Rodian"
"Saiyan"
"Spartoi"
"Strontian"
"Symbiote"
"Talokite"
"Tamaranean"
"Ungaran"
"Vampire"
"Xenomorph XX121"
"Yautja"
"Yoda's species"
"Zen-Whoberian"
"Zombie"
null

In addition, the superheroes shown should be updated every time the value in the input text field changes or the values chosen in the select element changes, not when the Submit button is pressed. To that end, you no longer need to include the Submit button.

Superheroes that are shown must still be sorted in increasing id number.

Info

For the purposes of this phase, the oninput key handler should give the most visually intuitive results (rather than onchange or onkeypress).

Info

The /all.json endpoint obtains the data for all the superheroes available in the API.

  • The search results are updated every time an input element's value changes.
  • Only the Human select option is chosen by default.
  • All information for all relevant superheroes is displayed properly.
  • The superheroes are still displayed in increasing id number.

Submission

Checkpoint

One ID, One Superhero (5 ❤️)

Do Phase 1 during the lab for extra heart points.

Via DCS Yagit (https://yagit.upd-dcs.work/). Submit individually.

Deadline: October 29, 2026 (Th) 11:12 pm

Your submission must have the following files:

index.html
main.py
README.md