================================================================================ CRUNCHYROLL DOWNLOADER - CHALLENGE 1 SOLUTION Chapter 6: Generalization & Extension Challenge: Spotify Adapter ================================================================================ PROBLEM: Adapt pattern to Spotify API: 1. Create SpotifyClient class 2. Implement login for Spotify OAuth 3. Fetch saved tracks 4. Export to CSV SOLUTION: ================================================================================ File: spotify_utils.py (Spotify adapter) import requests class SpotifyClient: """Spotify API client (same pattern as Crunchyroll).""" def __init__(self, config, token): self.config = config self.token = token self.base_url = "https://api.spotify.com/v1" self.headers = { "Authorization": f"Bearer {token}" } def get_saved_tracks(self): """Fetch user's saved tracks.""" url = f"{self.base_url}/me/tracks" response = requests.get(url, headers=self.headers) if response.status_code == 200: data = response.json() return data.get('items', []) else: print(f"❌ Error: {response.status_code}") return [] # THE PATTERN IS IDENTICAL: # 1. Client class with __init__ and _get() # 2. Headers with "Bearer {token}" # 3. Parse JSON response # 4. Export to CSV # Only differences: # - Base URL (Spotify vs Crunchyroll) # - Endpoint (/me/tracks vs /api/v2/episodes) # - Response structure (items field) # - Field names (track vs episode) THE GENERALIZATION ================================================================================ Pattern Template: class APIClient: def __init__(self, config, token): self.token = token self.headers = {"Authorization": f"Bearer {token}"} def get_data(self): response = requests.get(url, headers=self.headers) if response.status_code == 200: return response.json() return None Works for: - Crunchyroll API - Spotify API - Discord API - Twitch API - GitHub API - Any REST API with JWT/Bearer tokens! ================================================================================