Chapter 12

APIs

13.0 Intro · 13.1 API Basics · 13.2 API Reliability

← → or Space to navigate · F for fullscreen

12.1 API Basics

HTTP · requests.get() · JSON · query parameters · error handling

What is an API?

An API (Application Programming Interface) is a contract that lets programs talk to each other. A REST API uses HTTP to exchange data in JSON format.

HTTP Method Action
GET Read data
POST Create data
PUT Replace data
PATCH Update part of data
DELETE Remove data

Status codes

Code Meaning
200 OK — success
201 Created
400 Bad request
401 Unauthorized
404 Not found
429 Rate limited
500 Server error

requests.get() and JSON

import requests

url = "https://api.open-meteo.com/v1/forecast"
params = {
    "latitude": 37.95,
    "longitude": -91.77,
    "current": "temperature_2m",
}

response = requests.get(url, params=params,
                        timeout=10)
response.raise_for_status()   # raise on 4xx/5xx

data = response.json()
temp = data["current"]["temperature_2m"]
print(f"Temperature: {temp}°C")
# Given: {"users": [{"name": "Alice", "scores": [92, 88]}]}

data = response.json()

# Chained access
name = data["users"][0]["name"]

# Safe access with .get()
email = data["users"][0].get("email", "N/A")

# Loop over array
for user in data.get("users", []):
    print(user["name"])

12.2 API Reliability

Authentication · pagination · retry · defensive parsing

Authentication & API Keys

import os

# Store secrets in environment variables — never in code
api_key = os.environ["MY_API_KEY"]

# Bearer token
headers = {"Authorization": f"Bearer {api_key}"}

# X-API-Key header
headers = {"X-API-Key": api_key}

response = requests.get(url, headers=headers,
                        timeout=10)

POST with JSON body

payload = {
    "model": "gpt-4",
    "messages": [{"role": "user",
                  "content": "Hello"}]
}

response = requests.post(
    "https://api.openai.com/v1/chat/completions",
    headers={"Authorization": f"Bearer {api_key}"},
    json=payload,   # auto-encodes and sets Content-Type
    timeout=30,
)

Pagination & Retry

Page-based pagination

results = []
page = 1

while True:
    r = requests.get(url, params={"page": page},
                     timeout=10)
    r.raise_for_status()
    data = r.json()
    items = data.get("results", [])
    if not items:
        break
    results.extend(items)
    page += 1

Exponential backoff retry

import time

def get_with_retry(url, retries=3):
    for attempt in range(retries):
        try:
            r = requests.get(url, timeout=10)
            r.raise_for_status()
            return r.json()
        except requests.RequestException as e:
            if attempt == retries - 1:
                raise
            time.sleep(2 ** attempt)   # 1, 2, 4 s

Chapter 12 — Quick Reference

Concept Key syntax / notes
GET request requests.get(url, params={}, timeout=10)
POST request requests.post(url, json={}, headers={})
Raise on error .raise_for_status()
Parse JSON .json() → dict/list
Safe access data.get("key", default)
Auth header {"Authorization": f"Bearer {token}"}
API key Store in os.environ, never hard-coded
Pagination Loop until empty page
Retry Exponential backoff; max retries

End of Chapter 12

Next: Chapter 13 — Abstract Data Structures

stacks · queues · trees · graphs · ADT interface vs implementation