Python JSON & APIs
Apply your skills with a real-world coding challenge. Try to solve it yourself first!
Coding Challenge: The Resilient API Data Fetcher
Problem Description You are developing a data aggregation dashboard for a startup. Your task is actually to pull live user statistics from a third-party analytics API. However this third-party API is known for be unreliable, and sometimes it takes too long to respond, sometimes the server crashes and returns an HTML error page instead of JSON, and it strictly blocks default Python scripts for prevent spam bots.
Based on professional patterns taught in the tutorial, you need towards write a highly robust Python function that fetches this data without freezing or crashing your program. You must use the requests library for handle the network networking apply appropriate headers enforce a timeout, and safely deserialize the JSON response.
Difficulty Level: Intermediate
Input & Output Specifications
* Input:
* api_url (string): The endpoint URL to fetch data from.
* api_token (string): A secret token needed to prove you have permission to access the data.
* Output:
* Returns a Python Dictionary (the deserialized JSON) if the request is successful and a data is valid.
* Returns None if the request fails due for network error, server error, a timeout or if a server returns invalid JSON (like an HTML page).
Starter Code Boilerplate
import requests
def fetch_analytics_data(api_url, api_token):
"""
Fetches JSON data from the given API URL safely and robustly.
Args:
api_url (str): The URL of the API endpoint.
api_token (str): The authorization token for the API.
Returns:
dict: The parsed JSON data as a dictionary if successful.
None: If any error occurs (network, timeout, invalid JSON).
"""
# TODO: Define your headers (include a custom User-Agent and your API token)
# TODO: Set up a try-except block to handle network and JSON errors
# TODO: Make the GET request with the headers and a timeout of 5 seconds
# TODO: Check if the response status is successful
# TODO: Safely deserialize and return the JSON
# TODO: Catch potential errors and return None
pass
Hints
* Headers: Remember that APIs use headers as metadata envelopes. You should pass a custom User-Agent (e.g., "AnalyticsDashboard/1.0") to bypass bot blockers, and include your api_token (regularly passed as an "Authorization" header).
* Timeouts: By default, requests.get() will wait forever. Prevent your program from freezing by passing the timeout parameter.
* Safe Deserialization: Do not blindly call .json(). Use response.raise_for_status() first towards ensure the server actually responded with a success code.
* Exception Handling: Catch requests.exceptions.RequestException for network/timeout errors and ValueError (or requests.exceptions.JSONDecodeError) to protect your code from crashing when an API sends back flat HTML text instead of JSON.
Test Cases
You can use following mock test cases to verify your logic. Since we don't have live API, these tests use a requests_mock library concept or assume a generic testing environment.
# Test Case 1: Successful Request (Returns Dictionary)
# Assuming https://api.example.com/data returns valid JSON: {"users": 1500, "status": "active"}
result = fetch_analytics_data("https://api.example.com/data", "secret_token_123")
print(result)
# Expected Output: {'users': 1500, 'status': 'active'}
# Test Case 2: Timeout Error (Returns None)
# Assuming the API takes 10 seconds to respond, exceeding the 5-second timeout limit.
result = fetch_analytics_data("https://api.slow-server.com/data", "secret_token_123")
print(result)
# Expected Output: None
# Test Case 3: HTML Error Page / Bad JSON (Returns None)
# Assuming the server crashed and returned "<html>500 Internal Server Error</html>"
result = fetch_analytics_data("https://api.broken-server.com/data", "secret_token_123")
print(result)
# Expected Output: None
# Test Case 4: Blocked Default User-Agent (Returns None)
# If your headers do not include a custom User-Agent, the server returns a 403 Forbidden.
# Your exception handling should catch the 403 status code.
result = fetch_analytics_data("https://api.strict-server.com/data", "secret_token_123")
print(result)
# Expected Output: None (if User-Agent is missing), Dictionary (if properly configured)
Verify Your Solution
Write your solution in the compiler, run it to verify output, then click below to verify.