21 Chapter 11: Connected Programs
In this chapter, you’ll learn how to connect your programs to the internet. You’ll discover APIs (Application Programming Interfaces), make web requests, and process real-time data. This is where your programs join the global conversation!
21.1 Introduction: Your Programs Go Online
Remember when your programs could only work with data you typed in or saved in files? Those days are over! The internet is full of live data waiting for your programs to use: - Current weather from anywhere in the world - Live stock prices and currency rates - News headlines as they happen - Social media updates - And millions more data sources
This chapter teaches you to tap into this river of information.
21.2 Understanding APIs: How Programs Talk
An API (Application Programming Interface) is like a restaurant menu for programs. Just as a menu tells you what dishes you can order and how much they cost, an API tells your program what data it can request and how to ask for it.
The Restaurant Analogy
Think of APIs like this: 1. Menu (API Documentation) - Lists what’s available 2. Order (Request) - You ask for specific items 3. Kitchen (Server) - Prepares your data 4. Delivery (Response) - You receive what you ordered
Your First API Call
Let’s start with something fun - getting a random joke:
import requests
# Make a request to the joke API
response = requests.get("https://official-joke-api.appspot.com/random_joke")
# Convert the response to Python data
joke_data = response.json()
# Display the joke
print(joke_data['setup'])
print(joke_data['punchline'])This chapter uses the requests library. When AI suggests libraries, always ask: “How do I install this library? What does it do that Python can’t do by itself?”
21.3 How Web Requests Work
When your program “talks” to the internet, it follows a conversation pattern:
- Request: “Hey weather service, what’s the temperature in Boston?”
- Response: “It’s 72°F, partly cloudy”
The Request-Response Cycle
def get_weather(city):
"""Get current weather for a city"""
# 1. Build the request URL
base_url = "http://api.weatherapi.com/v1/current.json"
params = {
'key': 'your_api_key_here',
'q': city
}
# 2. Send the request
response = requests.get(base_url, params=params)
# 3. Check if it worked
if response.status_code == 200:
# 4. Extract the data
data = response.json()
return data['current']['temp_f']
else:
return NoneWhen working with new APIs, ask AI: “I want to use the [service] API. Show me the simplest possible example that gets one piece of data.”
21.4 Working with JSON Responses
Most APIs return data in JSON format - the same format you learned in Chapter 10! This makes it easy to work with.
Exploring API Responses
When you get data from an API, explore it first:
def explore_api_response(url):
"""Explore what an API returns"""
response = requests.get(url)
data = response.json()
# Print the structure
print("Response contains:")
for key in data.keys():
print(f" - {key}: {type(data[key])}")
return data
# Try it with a quote API
quote_data = explore_api_response("https://api.quotable.io/random")When you see data['current']['temp_f'], you’re accessing nested dictionaries. Ask AI: “Show me how to safely access nested dictionary values when keys might not exist.”
21.5 API Keys: Your Program’s ID Card
Many APIs require a key - like a password that identifies your program. Here’s how to handle them safely:
Getting and Using API Keys
- Sign up at the API provider’s website
- Get your key from your account dashboard
- Keep it secret - never put keys in your code!
- Use it in requests as shown below
def get_news_headlines():
"""Get top news headlines"""
# DON'T DO THIS - key exposed in code!
# api_key = "abc123mysecretkey"
# DO THIS - read from environment or file
with open('api_keys.txt', 'r') as f:
api_key = f.readline().strip()
url = "https://newsapi.org/v2/top-headlines"
params = {
'apiKey': api_key,
'country': 'us',
'pageSize': 5
}
response = requests.get(url, params=params)
return response.json()21.6 Building a Weather Dashboard
Let’s create something useful - a weather comparison tool:
def create_weather_dashboard(cities):
"""Compare weather across multiple cities"""
api_key = load_api_key('weather_key.txt')
weather_data = []
for city in cities:
url = f"http://api.weatherapi.com/v1/current.json"
params = {'key': api_key, 'q': city}
response = requests.get(url, params=params)
if response.status_code == 200:
data = response.json()
weather_data.append({
'city': city,
'temp': data['current']['temp_f'],
'condition': data['current']['condition']['text'],
'humidity': data['current']['humidity']
})
# Display the dashboard
print("\n🌤️ WEATHER DASHBOARD 🌤️")
print("=" * 40)
for weather in weather_data:
print(f"\n{weather['city']}:")
print(f" Temperature: {weather['temp']}°F")
print(f" Condition: {weather['condition']}")
print(f" Humidity: {weather['humidity']}%")21.7 Handling API Errors Gracefully
APIs can fail for many reasons. Your program needs to handle these gracefully:
Common API Problems
- No Internet Connection - Can’t reach the server
- Invalid API Key - Authentication failed
- Rate Limiting - Too many requests
- Server Errors - API is down
- Invalid Data - Unexpected response format
Error Handling Strategies
def safe_api_call(url, params=None):
"""Make an API call with error handling"""
try:
response = requests.get(url, params=params, timeout=5)
# Check status code
if response.status_code == 200:
return response.json()
elif response.status_code == 401:
print("Error: Invalid API key")
elif response.status_code == 429:
print("Error: Too many requests - slow down!")
else:
print(f"Error: {response.status_code}")
except requests.ConnectionError:
print("Error: No internet connection")
except requests.Timeout:
print("Error: Request timed out")
except Exception as e:
print(f"Unexpected error: {e}")
return NoneMost free APIs limit how many requests you can make. Always check the documentation and add delays between requests if needed:
import time
time.sleep(1) # Wait 1 second between requests21.8 Creating a Currency Converter
Let’s build something practical - a live currency converter:
def get_exchange_rate(from_currency, to_currency):
"""Get current exchange rate"""
url = "https://api.exchangerate-api.com/v4/latest/" + from_currency
response = requests.get(url)
if response.status_code == 200:
data = response.json()
rate = data['rates'].get(to_currency)
return rate
return None
def convert_currency(amount, from_currency, to_currency):
"""Convert between currencies"""
rate = get_exchange_rate(from_currency, to_currency)
if rate:
converted = amount * rate
print(f"{amount} {from_currency} = {converted:.2f} {to_currency}")
print(f"Exchange rate: 1 {from_currency} = {rate} {to_currency}")
else:
print("Could not get exchange rate")
# Use it
convert_currency(100, "USD", "EUR")21.9 Working with Different API Types
REST APIs (Most Common)
- Request specific URLs
- Get JSON responses
- Like ordering from a menu
Real-time APIs
- Continuous data streams
- Like a news ticker
- More complex to handle
GraphQL APIs
- Request exactly what you need
- Like a customizable menu
- Growing in popularity
21.10 Building a News Aggregator
Let’s create a program that collects news from multiple sources:
def get_tech_news():
"""Get latest technology news"""
api_key = load_api_key('news_key.txt')
# Get news from API
url = "https://newsapi.org/v2/top-headlines"
params = {
'apiKey': api_key,
'category': 'technology',
'pageSize': 10
}
response = requests.get(url, params=params)
if response.status_code == 200:
articles = response.json()['articles']
# Display headlines
print("\n📰 LATEST TECH NEWS")
print("=" * 50)
for i, article in enumerate(articles, 1):
print(f"\n{i}. {article['title']}")
print(f" Source: {article['source']['name']}")
print(f" {article['description'][:100]}...")
# Run the aggregator
get_tech_news()21.11 API Best Practices
1. Cache Responses
Don’t request the same data repeatedly:
cache = {}
def get_cached_weather(city):
if city not in cache:
cache[city] = fetch_weather_from_api(city)
return cache[city]2. Handle Timeouts
Networks can be slow:
response = requests.get(url, timeout=5) # 5 second timeout3. Validate Data
APIs can return unexpected data:
def safe_get(data, *keys):
"""Safely navigate nested dictionaries"""
for key in keys:
if isinstance(data, dict):
data = data.get(key)
else:
return None
return data
# Use: safe_get(data, 'current', 'temp_f')21.12 Creating Your API Toolkit
Build reusable functions for common patterns:
class APIClient:
"""Reusable API client"""
def __init__(self, base_url, api_key=None):
self.base_url = base_url
self.api_key = api_key
self.session = requests.Session()
def get(self, endpoint, params=None):
"""Make a GET request"""
url = self.base_url + endpoint
if self.api_key:
if params is None:
params = {}
params['api_key'] = self.api_key
try:
response = self.session.get(url, params=params)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"API Error: {e}")
return None
# Use your toolkit
weather_client = APIClient("http://api.weatherapi.com/v1/", api_key="your_key")
data = weather_client.get("current.json", {"q": "Boston"})21.13 Real Project: Multi-Source Dashboard
Let’s combine multiple APIs into one useful program:
def create_morning_briefing():
"""Get weather, news, and quote for the day"""
print("\n☀️ GOOD MORNING! Here's your briefing:\n")
# Weather
weather = get_weather("New York")
if weather:
print(f"🌡️ Weather: {weather['temp']}°F, {weather['condition']}")
# Motivational quote
quote = get_daily_quote()
if quote:
print(f"\n💭 Quote of the day: \"{quote['content']}\"")
print(f" - {quote['author']}")
# Top news
news = get_headlines(3)
if news:
print("\n📰 Top Headlines:")
for headline in news:
print(f" • {headline}")
# Currency rates
rates = get_currency_rates("USD", ["EUR", "GBP", "JPY"])
if rates:
print("\n💱 Currency Rates:")
for currency, rate in rates.items():
print(f" • 1 USD = {rate} {currency}")21.14 Common Pitfalls and Solutions
Pitfall 1: Hardcoding API Keys
Problem: Keys in code are security risks Solution: Use environment variables or secure files
Pitfall 2: No Error Handling
Problem: Program crashes when API fails Solution: Always use try/except blocks
Pitfall 3: Ignoring Rate Limits
Problem: API blocks your requests Solution: Add delays and check documentation
Pitfall 4: Not Checking Response Status
Problem: Assuming all requests succeed Solution: Always check status_code
21.15 Practice Projects
Project 1: Weather Tracker
- Track weather for multiple cities
- Store historical data
- Find weather patterns
- Alert for extreme conditions
Project 2: Stock Portfolio Monitor
- Track stock prices
- Calculate gains/losses
- Set price alerts
- Generate reports
Project 3: News Sentiment Analyzer
- Collect news articles
- Analyze headlines
- Track topics over time
- Create summaries
21.16 Looking Ahead
Next chapter, you’ll learn to create interactive programs with graphical interfaces. Instead of just printing to the console, your programs will have buttons, windows, and visual elements that users can click and interact with!
21.17 Chapter Summary
You’ve learned to: - Understand how APIs work - Make web requests from Python - Handle JSON responses - Manage API keys securely - Build programs that use live data - Handle errors gracefully
Your programs are no longer isolated - they’re connected to the world’s information!
21.18 Reflection Prompts
- API Design: What makes a good API vs a frustrating one?
- Error Planning: What could go wrong with internet-connected programs?
- Privacy Concerns: What data should programs be careful about?
- Future APIs: What APIs would you like to exist?
Remember: The internet is your program’s library. APIs are the librarians that help you find exactly what you need!