Unit 13 · lesson
Build a Remote Task Dashboard
Core path: 35 minutes
This week finally lets your Python program talk to software running somewhere else.
That also means you inherit failures you do not control: network problems, HTTP errors, slow responses, missing resources, and data that does not match what you expected.
The dashboard is built so the analysis logic still works even when the live service does not.
Inspect the data contract first
The live test endpoint is:
https://jsonplaceholder.typicode.com/users/1/todos
A normal record contains fields such as:
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
Create a local fixture named todos-sample.json:
[
{"userId": 1, "id": 1, "title": "inspect battery logs", "completed": true},
{"userId": 1, "id": 2, "title": "review failed test", "completed": false},
{"userId": 1, "id": 3, "title": "document recovery step", "completed": true},
{"userId": 1, "id": 4, "title": "verify dashboard output", "completed": false}
]
The fixture is controlled test data. It is not evidence that the internet worked.
That distinction must remain visible in the program.
Separate data acquisition from analysis
Install Requests in the selected project environment if needed:
python -m pip install requests
Then:
import json
import requests
def fetch_todos(user_id):
url = f"https://jsonplaceholder.typicode.com/users/{user_id}/todos"
response = requests.get(url, timeout=5)
response.raise_for_status()
return response.json()
def load_fixture(path="todos-sample.json"):
with open(path, "r", encoding="utf-8") as file:
return json.load(file)
Keep the analysis separate:
def analyze_todos(todo_list):
total = len(todo_list)
completed = 0
pending_titles = []
for todo in todo_list:
if todo["completed"]:
completed += 1
else:
pending_titles.append(todo["title"])
return {
"total": total,
"completed": completed,
"pending": total - completed,
"pending_titles": pending_titles,
}
Now analyze_todos() does not care whether the list came from the network or a local file.
That is a useful boundary.
Add a controlled fallback
try:
todos = fetch_todos(user_id)
source_label = "LIVE API"
except requests.exceptions.RequestException as error:
print(f"Live request unavailable: {error}")
todos = load_fixture()
source_label = "LOCAL FIXTURE"
The fallback should be explicit.
If the program quietly displays fixture data while pretending the live request succeeded, the dashboard becomes misleading.
Print the source label in the report.
Display evidence, not just numbers
Show:
Source:
Total tasks:
Completed:
Pending:
Pending titles:
Limit the title list to a few entries so the dashboard remains readable.
Test different failure layers
Record evidence for at least three states when your environment allows it:
- a reachable live request;
- an invalid or unavailable live resource;
- the local fixture path.
If the network is blocked by school controls, do not bypass them. The fixture exists so the core analysis remains testable offline.
For each case, identify which layer changed:
network / transport
HTTP response
JSON/data
analysis logic
Do not label every failure "the API broke."
Success evidence
Your dashboard should demonstrate:
- a timeout on the live request;
raise_for_status()or equivalent HTTP failure handling;- a local JSON fixture;
- acquisition separate from analysis;
- a source label that tells the truth;
- correct counts from the fixture; and
- evidence from more than one runtime state.
The internet adds another system boundary. Treat it like one.