Chapter 20: Exercises

Working with External APIs and Integrations

These exercises progress from foundational knowledge through advanced application. Complete them in order, as later exercises build on skills developed in earlier ones.


Tier 1: Remember and Understand (Exercises 1-6)

Exercise 1: API Authentication Methods

List the four most common API authentication methods discussed in this chapter. For each, provide a one-sentence description and an example of when you would use it.

Exercise 2: OAuth 2.0 Flow Identification

For each of the following scenarios, identify the appropriate OAuth 2.0 grant type and explain your reasoning: - A web application that needs to access a user's Google Calendar - A backend service that processes nightly analytics from a third-party API - A command-line tool that needs to authenticate a developer with GitHub - A single-page React application that needs to access a user's Dropbox files

Exercise 3: Circuit Breaker States

Draw a state diagram showing the three states of a circuit breaker (Closed, Open, Half-Open). Label each transition with the condition that triggers it. Then explain in your own words why the Half-Open state is necessary.

Exercise 4: Rate Limit Headers

Given the following HTTP response headers, answer the questions below:

HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 15
X-RateLimit-Reset: 1700000000
Retry-After: 45
  1. What is the maximum number of requests allowed in the current window?
  2. How many requests can the client still make?
  3. What should the client do if it receives a 429 response with these headers?

Exercise 5: Webhook vs. Polling

Compare webhooks and polling for receiving updates from an external service. Create a table with at least five criteria (e.g., latency, complexity, resource usage) and evaluate each approach against those criteria.

Exercise 6: Idempotency in Payments

Explain why idempotency keys are critical for payment processing. Describe a specific scenario where the lack of an idempotency key could lead to a customer being charged twice. Then explain how an idempotency key prevents this.


Tier 2: Apply (Exercises 7-12)

Exercise 7: Basic API Client

Write a Python class GitHubAPIClient that: - Uses httpx to make requests to the GitHub REST API - Accepts a personal access token for authentication - Implements methods: get_user(username), list_repos(username), and get_repo(owner, repo) - Sets appropriate timeouts and headers - Raises meaningful exceptions on errors

Exercise 8: Token Refresh Implementation

Implement a TokenManager class that: - Stores an access token and its expiration time - Provides a method get_token() that returns a valid token - Automatically refreshes the token when it is within 60 seconds of expiring - Uses a mock token endpoint (you can simulate the HTTP call) - Includes proper error handling for failed refresh attempts

Exercise 9: Retry with Exponential Backoff

Write a function retry_request() that: - Accepts an async function and its arguments - Retries on 5xx errors and connection timeouts - Uses exponential backoff with jitter - Has a configurable maximum number of retries (default 3) - Has a configurable maximum delay (default 60 seconds) - Does NOT retry on 4xx errors (except 429) - For 429 errors, respects the Retry-After header

Exercise 10: Webhook Signature Verification

Implement a FastAPI endpoint that: - Receives webhook payloads at POST /webhooks/github - Verifies the X-Hub-Signature-256 header using HMAC-SHA256 - Parses the event type from the X-GitHub-Event header - Routes events to appropriate handler functions (at least: push, pull_request, issues) - Returns 401 for invalid signatures and 200 for successfully processed events

Exercise 11: Simple Rate Limiter

Implement a SlidingWindowRateLimiter class that: - Tracks request timestamps in a sliding window - Accepts max_requests and window_seconds parameters - Provides an async acquire() method that blocks until a request can be made - Provides a can_proceed() method that returns True/False without blocking - Cleans up old timestamps to prevent memory leaks

Exercise 12: Email Service Abstraction

Create an EmailService abstract base class and two concrete implementations: - SendGridEmailService that formats requests for the SendGrid API - MailgunEmailService that formats requests for the Mailgun API - Both should implement send(to, subject, html_body, text_body) and send_template(to, template_id, variables) - Write a factory function that returns the appropriate implementation based on a configuration string


Tier 3: Analyze (Exercises 13-18)

Exercise 13: API Client Code Review

Review the following API client code and identify at least five problems. For each problem, explain the issue and provide the corrected code:

import requests

def get_weather(city):
    url = f"http://api.weather.com/v1/weather?city={city}&key=abc123hardcoded"
    response = requests.get(url)
    return response.json()

def get_forecast(city, days):
    url = f"http://api.weather.com/v1/forecast?city={city}&days={days}&key=abc123hardcoded"
    response = requests.get(url)
    data = response.json()
    return data["forecast"]["daily"]

Exercise 14: Rate Limit Strategy Analysis

A service you depend on has the following rate limits: - 100 requests per minute for the standard tier - Burst allowance of 10 requests per second - Daily limit of 10,000 requests - Each request can return up to 100 items

Your application needs to sync 50,000 items per day. Analyze the rate limits and design a strategy that: 1. Stays within all rate limit tiers 2. Maximizes throughput 3. Handles the case where rate limits are temporarily exceeded 4. Includes a fallback plan if the daily limit is reached before all items are synced

Exercise 15: OAuth Security Analysis

Analyze the following OAuth implementation and identify security vulnerabilities:

@app.get("/auth/callback")
async def oauth_callback(code: str, state: str):
    # Exchange code for token
    token_response = await httpx.AsyncClient().post(
        "https://auth.example.com/token",
        data={
            "grant_type": "authorization_code",
            "code": code,
            "client_id": "my_client_id",
            "client_secret": "my_secret_embedded_here",
            "redirect_uri": "http://localhost:8000/auth/callback",
        },
    )
    token_data = token_response.json()

    # Store token in cookie
    response = RedirectResponse("/dashboard")
    response.set_cookie("access_token", token_data["access_token"])
    return response

List every security issue you can find, explain why each is problematic, and provide the corrected implementation.

Exercise 16: Webhook Reliability Analysis

Your application receives webhooks from a payment processor. Analyze the following scenario and answer the questions:

  1. A webhook is sent but your server is temporarily down. The payment processor retries 3 times over 24 hours. What mechanisms should you have in place to handle this?
  2. Your server receives the same webhook event 4 times (initial + 3 retries) because your 200 responses were not received by the payment processor due to network issues. How do you ensure the order is only fulfilled once?
  3. A webhook arrives for a payment success, but the corresponding order does not exist in your database yet (race condition). How do you handle this?

Exercise 17: Integration Architecture Comparison

Compare two architectures for an e-commerce checkout system:

Architecture A: Synchronous - Client submits order - Server creates payment, sends email, generates invoice, updates inventory -- all in the request handler - Returns result to client

Architecture B: Event-Driven - Client submits order - Server creates payment and publishes an "order.created" event - Background workers handle email, invoice, inventory updates - Client polls for status or receives WebSocket updates

For each architecture, analyze: reliability, latency, complexity, error handling, and scalability. Which would you recommend for a startup vs. a large-scale operation? Explain your reasoning.

Exercise 18: API Dependency Mapping

You are building a travel booking application that depends on these external services: - Flight search API (3 providers for redundancy) - Hotel search API (2 providers) - Payment processor - Email service - SMS notification service - Currency exchange rate API - Weather API for destination forecasts

Create a dependency map showing: 1. Which services are critical (booking fails without them) vs. optional (booking succeeds but with degraded experience) 2. Which services can be cached and for how long 3. Which services need real-time data 4. Your fallback strategy for each service category


Tier 4: Evaluate (Exercises 19-24)

Exercise 19: SDK vs. Direct API Calls

Evaluate the trade-offs between using an official SDK (e.g., stripe Python package) versus making direct HTTP calls (e.g., httpx) for the following criteria: - Maintenance burden - Flexibility - Testing - Dependency management - Documentation - Error handling - Performance

For a new project, write a recommendation with justification for when to use each approach.

Exercise 20: Circuit Breaker Tuning

You have a circuit breaker protecting calls to an email service. Evaluate the following configurations and recommend the best one for a production e-commerce application. Justify your choice.

Config A: failure_threshold=3, recovery_timeout=10s, success_threshold=1 Config B: failure_threshold=5, recovery_timeout=30s, success_threshold=2 Config C: failure_threshold=10, recovery_timeout=120s, success_threshold=5

Consider: What happens during brief network blips? What about sustained outages? What about slow recovery scenarios?

Exercise 21: Payment Integration Comparison

Compare two approaches to payment integration:

Approach A: Client-Side Tokenization - Client-side JavaScript widget collects card details - Card details sent directly to payment processor - Token returned to client, then sent to your server - Server creates payment using token

Approach B: Server-Side Redirect - Server creates a checkout session with the payment processor - Client is redirected to the payment processor's hosted page - Payment processor redirects back to your server after payment - Server receives payment confirmation via redirect and webhook

Evaluate each approach for: PCI compliance burden, user experience, customization ability, mobile support, and error handling complexity.

Exercise 22: Retry Strategy Evaluation

Evaluate the following retry strategies for a critical API call that sends appointment reminders via SMS:

  1. Immediate retry: Retry up to 3 times with no delay
  2. Fixed delay: Retry up to 3 times with 5-second delay
  3. Exponential backoff: Retry up to 5 times with 1s, 2s, 4s, 8s, 16s delays
  4. Exponential backoff with jitter: Same as above but with random 0-1s added to each delay
  5. Exponential backoff with dead letter queue: Retry 3 times, then send to a queue for manual review

Which strategy would you recommend and why? What factors influenced your decision?

Exercise 23: API Versioning Impact Assessment

An external API you depend on announces they are deprecating v2 and migrating to v3. The changes include: - Different authentication method (API key in header instead of query parameter) - Changed response format (nested objects instead of flat) - New required fields on several endpoints - Removed two endpoints you use (replaced by one combined endpoint) - Rate limits changed from 100/min to 60/min

Evaluate the impact on your application and create a migration plan. Consider: How do you run both versions simultaneously during migration? How do you test the migration? What is your rollback plan?

Exercise 24: Multi-Provider Fallback Evaluation

Design and evaluate a fallback system for an email sending service that uses three providers (SendGrid, Mailgun, Amazon SES). Consider: 1. How do you detect that a provider is failing? 2. In what order do you try providers? 3. How do you prevent duplicate sends when failing over? 4. How do you handle the case where all providers are down? 5. How do you automatically recover when a failed provider comes back online?

Write the evaluation as a design document with trade-offs clearly stated.


Tier 5: Create (Exercises 25-30)

Exercise 25: Universal API Client Library

Build a reusable Python library called api_toolkit that provides: - A base APIClient class with configurable retry logic, rate limiting, and circuit breaker - Automatic request/response logging - Token management with automatic refresh - Response caching with configurable TTL - A clean interface for subclassing to create service-specific clients

Write at least three service-specific clients using your library (e.g., GitHub, weather, currency exchange).

Exercise 26: Webhook Testing Framework

Create a webhook testing tool that: - Runs a local HTTP server to receive webhooks - Generates properly signed test payloads for common services (Stripe, GitHub) - Records all received webhooks with full headers and body - Provides assertion helpers (e.g., assert_received(event_type="payment.succeeded")) - Supports replaying recorded webhooks - Can be used as a pytest fixture

Exercise 27: Integration Health Dashboard

Build a FastAPI application that: - Monitors the health of 5+ external service integrations - Periodically checks each service's availability and response time - Displays a dashboard showing current status, uptime percentage, and response time graphs - Sends alerts (via one of the monitored services, with fallback) when a service goes down - Provides a REST API for programmatic health checks - Stores historical health data

Exercise 28: Multi-Service Data Aggregator

Build a data aggregation service that: - Accepts a city name and returns a comprehensive profile including: - Current weather (from a weather API) - Geographic coordinates (from a geocoding API) - Current time and timezone - Currency information for the country - A relevant news headline - Fetches all data concurrently - Caches results appropriately (different TTLs for different data types) - Handles partial failures gracefully (returns available data with indicators for failed services) - Includes comprehensive error handling and logging

Exercise 29: Payment Integration Test Suite

Create a comprehensive test suite for a payment integration that: - Tests the complete payment lifecycle: create intent, confirm, capture, refund - Tests error scenarios: declined cards, expired cards, insufficient funds, network timeouts - Tests webhook handling: signature verification, event routing, idempotent processing - Tests concurrent payment processing - Uses mocks for unit tests and a sandbox environment for integration tests - Generates a coverage report showing which payment scenarios are tested

Exercise 30: Integration Orchestration System

Build a complete integration orchestration system for an e-commerce platform that: - Receives order events and coordinates multiple external service calls - Implements the Saga pattern for distributed transactions (e.g., if email fails after payment succeeds, the system tracks the failure and retries) - Provides a retry queue with configurable retry policies per service - Implements circuit breakers for each external service - Logs all integration events in a structured format for debugging - Provides an admin API to view integration status, retry failed operations, and manually trigger integrations - Includes comprehensive tests with mocked external services


Submission Guidelines

  • All Python code must include type hints, docstrings, and follow PEP 8 conventions.
  • Include a requirements.txt listing all dependencies.
  • Write at least 3 unit tests for each coding exercise.
  • For Tier 4-5 exercises, include a brief write-up (200-500 words) explaining your design decisions.
  • Use environment variables for all secrets and API keys -- never hardcode them.