Preparing your learning space...
33% through FDE Projects tutorials
An API Data Dashboard pulls live data from an API and shows it in a clean, readable view. As a Forward Deployed Engineer this is your bread and butter — your customer's data lives inside APIs, and a dashboard is often the fastest way to make it useful. This tutorial builds a simple dashboard in Python with requests and Plotly.
A dashboard has three parts: a source (the API), a processing layer (turn JSON into data you can plot), and a view (charts and numbers). The whole trick is plumbing API responses into a visual without hard-coding values.
Here we use a public demo API so you can run everything. https://jsonplaceholder.typicode.com/todos returns a list of fake tasks — perfect for a first dashboard.
The requests library fetches a URL and returns the response as a Response object.
import requests
url = "https://jsonplaceholder.typicode.com/todos"
response = requests.get(url)
response.raise_for_status() # raise an error if the call failed
data = response.json() # parse the body as JSON
print(len(data)) # how many records came back
raise_for_status() is important — it stops your script silently continuing on a failed call. response.json() turns the JSON body into Python data you can work with.
Note: APIs often need a header (like an API key). Add one with
requests.get(url, headers={"Authorization": "Bearer YOUR_KEY"}).
API responses are usually a list of dicts. Use pandas to load them into a DataFrame so you can analyze and plot.
import pandas as pd
df = pd.DataFrame(data)
df["completed"] = df["completed"].astype(int) # bool -> 0/1 for math
print(df.head())
Now each record is a row and each field a column. Converting completed to an integer lets you sum it to count finished tasks.
Plotly makes interactive charts with one px call. Pass the DataFrame column directly.
import plotly.express as px
# Count how many todos each user has
counts = df.groupby("userId").size()
fig = px.bar(x=counts.index, y=counts.values,
labels={"x": "User ID", "y": "Number of todos"},
title="Todos per user")
fig.show()
groupby tallies records per user, then px.bar draws the bars. fig.show() opens the chart in your browser where it's interactive.
Real dashboards update. Wrap the fetch-and-plot work in a function and call it again when you want fresh data.
import time
def refresh():
response = requests.get(url).json()
df = pd.DataFrame(response)
completed = int(df["completed"].sum())
print(f"Total: {len(df)} | Completed: {completed}")
refresh()
time.sleep(10) # wait, then fetch again
refresh()
This is a light version of what a live dashboard does on a timer. For a persistent dashboard you'd run this loop on a schedule rather than in a script.
A complete, reusable dashboard for any paginated JSON API.
import requests
import pandas as pd
import plotly.express as px
API = "https://jsonplaceholder.typicode.com/todos"
def fetch_all(api, max_pages=20):
all_rows = []
page = 1
while page <= max_pages:
r = requests.get(api, params={"page": page, "limit": 50}).json()
if not r: # server returned zero records -> stop
break
all_rows.extend(r)
page += 1
return all_rows
rows = fetch_all(API)
df = pd.DataFrame(rows)
df["completed"] = df["completed"].astype(int)
# Summary numbers
total = len(df)
done = int(df["completed"].sum())
print(f"Total {total} | Done {done} | Open {total-done}")
# Chart
counts = df.groupby("userId").size()
fig = px.bar(x=counts.index, y=counts.values, title="Todos per user")
fig.show()
The fetch_all function requests one page at a time, extends the list with each page, and stops when a page comes back empty or the page cap is hit. The max_pages guard matters: jsonplaceholder ignores the page/limit params and returns the full list every time, so without the cap the loop would never terminate. On a real API, shape the params dict to match that API's pagination convention (page, offset, cursor, etc.), and confirm each page actually gets smaller before trusting the loop. Swap the URL and the summary numbers are yours.
Save your progress and earn XP for completing tutorials.
4 questions · Pass with 70%+
1What does response.json() return?
2Why call response.raise_for_status() after a request?
3Your pagination loop fetches forever because the API ignores page and always returns the full list. Best fix?
4You want a bar chart of "number of todos per user." How do you group the data first?
Technology
Forward Deployed Engineer
Lesson group
FDE Projects
Progress
33% complete