What’s one thing you learned? What’s still confusing?
The collections Module
Counter, defaultdict, OrderedDict, namedtuple, deque, plus heapq and bisect.
Regular Expressions: Pattern Matching Mastery
Regex patterns, groups, lookahead/lookbehind, and real-world text processing.
NumPy & Pandas: The Data Science Toolkit
NumPy arrays, vectorization, broadcasting, and Pandas DataFrames.
Interactive Labs for This Track
Loop Visualizer
You're a factory robot repeating the same task on an assembly line — watch how loops automate repetitive work
List Slicing
You have a playlist of 50 songs — grab just tracks 10 through 20 with a single slice expression
Sorting Algorithms
You're organizing a library of 10,000 books — which sorting method is fastest?
Ask questions, share insights
requests is the most-downloaded Python library (300M+ downloads/month), and httpx is its async-native successor. Master both, and you've mastered how Python talks to the rest of the world.pip install requests
requests is the most downloaded Python package in the world — used in over 1 million projects.import requests
# GET request — fetch data from a URL
response = requests.get("https://api.github.com/users/python")
# Check if it worked
print(response.status_code) # 200 = success, 404 = not found, 429 = rate limited
# Get the JSON data as a Python dict
data = response.json()
print(data["name"]) # "Python"
print(data["public_repos"]) # number of public repositoriesresponse object.json() → get a Python dictresponse = requests.get("https://api.github.com/users/python")
# Status code tells you what happened
print(response.status_code) # 200 = OK, 201 = Created, 400 = Bad Request
print(response.ok) # True if status_code < 400
# Headers contain metadata
print(response.headers["Content-Type"]) # "application/json; charset=utf-8"
# The body — as text or parsed JSON
print(response.text) # raw JSON string
print(response.json()) # Python dict (use this)200 OK — worked perfectly201 Created — created a new resource (POST succeeded)400 Bad Request — you sent something wrong401 Unauthorized — you need an API key429 Too Many Requests — you hit the rate limit, slow down500 Internal Server Error — the server broke, not your faultMost real APIs require an API key — your "membership card" that proves you're allowed in.
import requests
import os
API_KEY = os.environ.get("MY_API_KEY") # Always read from environment, never hardcode
# Method 1: Authorization header (most common)
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
response = requests.get("https://api.example.com/data", headers=headers)
# Method 2: Query parameter (some APIs use this)
response = requests.get(
"https://api.example.com/data",
params={"api_key": API_KEY, "format": "json"}
)
# Method 3: Custom header (Anthropic API style)
headers = {
"x-api-key": API_KEY,
"anthropic-version": "2023-06-01",
"content-type": "application/json"
}GET fetches data. POST sends data. LLM APIs use POST because you're sending a prompt.
import requests
import json
# POST request — send JSON data to an API
url = "https://api.anthropic.com/v1/messages"
headers = {
"x-api-key": "your-key-here",
"anthropic-version": "2023-06-01",
"content-type": "application/json"
}
payload = {
"model": "claude-sonnet-4-5",
"max_tokens": 500,
"messages": [
{"role": "user", "content": "Explain Python in one sentence."}
]
}
response = requests.post(url, headers=headers, json=payload)
data = response.json()
print(data["content"][0]["text"])json=payload vs data=json.dumps(payload)json=payload automatically sets the Content-Type header and serializes the dict. Use it.import requests
from requests.exceptions import RequestException, Timeout, ConnectionError
def call_api_safely(url: str, headers: dict) -> dict | None:
"""Call an API with proper error handling."""
try:
response = requests.get(url, headers=headers, timeout=10) # 10s timeout
# Raise an exception for bad status codes (4xx, 5xx)
response.raise_for_status()
return response.json()
except Timeout:
print("Request timed out — server took too long")
except ConnectionError:
print("No internet connection or server is down")
except requests.HTTPError as e:
print(f"HTTP error: {e.response.status_code} — {e.response.text}")
except RequestException as e:
print(f"Something went wrong: {e}")
return NoneMany APIs return results in pages — they can't send 10,000 results at once.
import time
def get_all_results(base_url: str, headers: dict) -> list:
"""Fetch all pages of results from a paginated API."""
results = []
page = 1
while True:
response = requests.get(
base_url,
headers=headers,
params={"page": page, "per_page": 100},
timeout=10,
)
response.raise_for_status()
data = response.json()
# No more results — stop
if not data:
break
results.extend(data)
page += 1
# Respect rate limits — pause between requests
time.sleep(0.1)
return resultsimport requests
import os
import json
def get_repo_info(username: str, repo: str) -> dict:
"""Fetch GitHub repository info — no auth needed for public repos."""
url = f"https://api.github.com/repos/{username}/{repo}"
response = requests.get(url, timeout=10)
response.raise_for_status()
data = response.json()
return {
"name": data["full_name"],
"stars": data["stargazers_count"],
"language": data["language"],
"description": data["description"],
"last_updated": data["updated_at"][:10], # just the date part
}
# Usage
info = get_repo_info("anthropics", "anthropic-sdk-python")
print(f"⭐ {info['stars']} stars")
print(f"🔤 Written in {info['language']}")
print(f"📝 {info['description']}")Interactive Lab
See how LLM API calls work step by step — request structure, response parsing, and tool use patterns
What does response.raise_for_status() do?