Skip to main content

Stage 10: It's Connected

Course progressStage 10 of 10
~45 min
Build

a live-internet skill and your assistant's own personality

Learn

how requests pulls real data from the web, and how to ship a demo

Ship

a personalized, internet-connected assistant ready for parent day

A finished Python assistant connected to the internet and ready for a parent-day demo
Target: your finished assistant demoThe final assistant has personality, memory, a live internet skill, and a short demo sequence you can show.

The big idea

Everything your assistant knows so far, you put there. Today it reaches outside — to the live internet — and brings back something brand new that nobody typed into your file. This is the climax of the whole week.

The tool is the requests package, which you installed with uv back in Setup. A web API is a website built for programs instead of people — you ask it a question and it sends back data, not a web page. We'll ask a free joke website for a fresh joke. requests.get(url) fetches the answer, and .json() reads it into a dictionary you already know how to use.

Then we make it yours — a custom name, a catchphrase, a personality. By the end of this stage you don't have "an assistant." You have your assistant.

New words
requests
An installed package that fetches data from the internet in one line.
web API
A website built for programs to talk to. You ask, it sends back data.
try / except
Run risky code in try; if it fails, except catches the problem instead of crashing.
Before you start

Make sure you finished Stage 9: It Remembers, and that you're online — this stage talks to the internet. (requests was installed by uv add rich requests in Setup.)

Build it

Step 1 — Import requests and add the live-joke skill

Add import requests at the top. Then write a skill that fetches a fresh joke. Because the internet can be slow or down, we wrap it in try/except — if the fetch fails, the assistant falls back to a joke it already knows instead of crashing.

Trace it

Trace the live fetch

  1. requests.get(url) asks the joke website for a random joke.
  2. .json() turns the website's answer into a dictionary with a "setup" and a "punchline".
  3. speak(...) says both parts out loud.
  4. If anything goes wrong (no internet), except runs the backup joke instead.
Python code task
Update your imports

assistant.py

Where it goes: Add import requests at the top with your other imports.

requests was installed by uv in Setup.

import requests
Python code task
Add to your file

assistant.py

Where it goes: Add this function with your other skill functions, above the loop.

The try/except keeps the demo safe even if the internet drops.

def online_joke():
try:
response = requests.get("https://official-joke-api.appspot.com/random_joke", timeout=5)
data = response.json()
speak(data["setup"])
speak(data["punchline"])
except Exception:
speak("I can't reach the internet right now, so here's one I know.")
tell_joke()
Python code task
Update your file

assistant.py

Where it goes: Add this branch inside the loop, right BEFORE your joke branch, so 'online' wins over plain 'joke'.

Distinct keywords so a fresh joke and a built-in joke don't collide.

elif "online" in command or "internet" in command or "fresh" in command:
online_joke()

Run it and type fresh joke or online joke. Your assistant reaches across the internet and tells you a joke that was never in your file. That sound is your code talking to another computer somewhere in the world.

Step 2 — Make it yours

Now give it a personality. Add a name and a catchphrase as variables at the top, then use them in the startup banner so the whole thing feels custom.

Think first

Why variables for the name?

We put the name in a variable ASSISTANT_NAME at the top instead of typing it in five places. Why is that better?

Check your thinking

One place to change it. Rename your assistant once at the top and every line that uses ASSISTANT_NAME updates automatically — no hunting through the file.

Python code task
Update your file

assistant.py

Where it goes: Add these two lines right under console = Console().

Change the name and catchphrase to whatever makes this assistant YOURS.

ASSISTANT_NAME = "Pixel"
CATCHPHRASE = "Beep boop — let's make something cool!"
Python code task
Update your file

assistant.py

Where it goes: Replace your three startup banner lines (from Stage 7) with these four.

Now the banner uses your custom name and catchphrase.

console.print(f"[bold green]==== {ASSISTANT_NAME.upper()} ====[/bold green]")
console.print("[cyan]Your Python assistant is online.[/cyan]")
speak(f"Hi! I'm {ASSISTANT_NAME}, your assistant.")
speak(CATCHPHRASE)

Add online to your show_help list too, so people can find your newest skill. Run it one more time and meet your finished, named, internet-connected assistant.

Step 3 — Rehearse your demo

On parent day you'll run your assistant and show it off. Practice this exact sequence so it flows:

  1. Run it: uv run assistant.py. Let the banner and catchphrase play.
  2. Type your name when it asks.
  3. hello — it greets you by name.
  4. tell me a joke — a built-in joke.
  5. what time is it — the real time.
  6. remember my favorite game is Minecraft, then what is my favorite game — it remembers.
  7. fresh joke — a live joke off the internet.
  8. quit — a clean goodbye.

If the room's internet is shaky, your try/except has you covered — step 7 still works with a backup joke. Nothing can crash your demo.

Understand it

The live-joke skill is small but it's a genuinely big idea: your program is no longer alone on your Mac. It can ask other computers for information, which is how almost every app you use works — weather, scores, messages, maps. You did it with one requests.get and the dictionary skills you already had. The internet stopped being magic and became something you can program.

We wrapped that fetch in try/except for a reason that matters most exactly when it counts: in front of an audience. Risky code — anything that depends on a network — should never be allowed to crash the whole program. Catching the failure and offering a graceful backup is what separates a fragile script from something you can confidently demo. Planning for the moment things go wrong is a mark of a real engineer.

Try this

Learning beat

Try this

Three short experiments. Predict before you run, then test your guess.

Predict first

Turn off the Wi-Fi and type fresh joke. Predict what your assistant will do. Then try it. Did your try/except save the day?

Compare

Change ASSISTANT_NAME at the top to something new and run it. Compare how different the same program feels with a different name and catchphrase. That's personality, and it's all yours.

Connect

You just pulled a joke off the internet. What else lives on the internet that your assistant could fetch — facts, weather, word definitions? Every one of those is another skill you now know how to build.

Test your stage

Stuck? Compare carefully
Answer check
Debug compare only

assistant.py

Where it goes: Compare this against your whole file. Use it only if your program won't run. This is the finished assistant.

This is the complete assistant.py at the end of the course.

import subprocess
import random
import datetime
import math
import requests
from rich.console import Console


console = Console()

ASSISTANT_NAME = "Pixel"
CATCHPHRASE = "Beep boop — let's make something cool!"


def speak(text):
print(text)
subprocess.run(["say", text])


def greet(person):
speak(f"Hello again, {person}!")


def say_bye():
speak("See you later!")


def show_help():
console.print("[bold cyan]I can do:[/bold cyan] hello, bye, joke, online, time, date, roll, math, remember, what is, help, quit")
speak("Here are my commands. They're on the screen.")


jokes = [
"Why did the computer go to the doctor? It caught a virus!",
"Why was the math book sad? It had too many problems.",
"What do you call a bear with no teeth? A gummy bear!",
"Why do programmers prefer dark mode? Because light attracts bugs!",
]

memory = {}


def tell_joke():
joke = random.choice(jokes)
speak(joke)


def online_joke():
try:
response = requests.get("https://official-joke-api.appspot.com/random_joke", timeout=5)
data = response.json()
speak(data["setup"])
speak(data["punchline"])
except Exception:
speak("I can't reach the internet right now, so here's one I know.")
tell_joke()


def tell_time():
now = datetime.datetime.now()
speak("The time is " + now.strftime("%I:%M %p") + ".")


def tell_date():
today = datetime.date.today()
speak("Today is " + today.strftime("%A, %B %d") + ".")


def roll_dice():
number = random.randint(1, 6)
speak(f"You rolled a {number}.")


def do_math():
number = input("Square root of what number? ")
answer = math.sqrt(float(number))
speak(f"The square root of {number} is {answer}.")


console.print(f"[bold green]==== {ASSISTANT_NAME.upper()} ====[/bold green]")
console.print("[cyan]Your Python assistant is online.[/cyan]")
speak(f"Hi! I'm {ASSISTANT_NAME}, your assistant.")
speak(CATCHPHRASE)

name = input("What is your name? ")
speak(f"Nice to meet you, {name}!")
speak(f"Type commands, {name}. Type help to hear what I can do.")

while True:
command = input("> ").lower().strip()

if "quit" in command or "exit" in command:
speak("Goodbye for now!")
break
elif "remember" in command and " is " in command:
fact = command.replace("remember", "").strip()
key, value = fact.split(" is ", 1)
memory[key.strip()] = value.strip()
speak(f"Okay, I'll remember that {key.strip()} is {value.strip()}.")
elif "hello" in command:
greet(name)
elif "bye" in command:
say_bye()
elif "online" in command or "internet" in command or "fresh" in command:
online_joke()
elif "joke" in command:
tell_joke()
elif "time" in command:
tell_time()
elif "date" in command:
tell_date()
elif "roll" in command or "dice" in command:
roll_dice()
elif "math" in command:
do_math()
elif command.startswith("what is") or command.startswith("what's"):
thing = command.replace("what is", "").replace("what's", "").strip().rstrip("?").strip()
if thing in memory:
speak(f"{thing} is {memory[thing]}.")
else:
speak("I don't know that yet. Teach me by saying remember.")
elif "help" in command:
show_help()
else:
speak("I'm not sure what you mean. Type help.")
  • fresh joke fetches and speaks a joke from the internet.
  • With the internet off, fresh joke falls back to a built-in joke instead of crashing.
  • Your assistant starts with your custom name and catchphrase.
  • You can run the whole parent-day demo sequence without a hitch.
  • Design check. Does your assistant feel like yours — its name, catchphrase, jokes, and colors? Make one last change that's purely you.

If it breaks

  • ModuleNotFoundError: No module named 'requests'. Run with uv run assistant.py, and confirm uv add rich requests finished in Setup. The uv run part is what loads requests.
  • fresh joke does nothing or waits a long time. The internet may be slow or off. The timeout=5 gives up after 5 seconds and your except runs the backup joke. Check the lab's Wi-Fi.
  • KeyError: 'setup'. The website sent back something unexpected. Your try/except should catch it; make sure the speak(data["setup"]) lines are inside the try.
  • fresh joke tells a built-in joke instead of an online one. Make sure the online branch is above the joke branch, since "online joke" contains the word "joke".