Goal: a reproducible, hands-on tutorial for BI engineers to learn consuming BI report APIs (auth, pagination, filters, error handling, verification) with Python examples and exercises.Prerequisites:- Familiarity: REST APIs, JSON, basic Python (requests), virtualenv- Tools installed: Python 3.9+, pip, curl, Postman, git- Accounts: API key or OAuth client for the BI platform, access to a sandbox workspace with sample reportsTutorial Outline & Exercises:1) Setup (15 min)- Create virtualenv, clone repo with sample code, install requirements.- Verify: run python -c "import requests; print(requests.__version__)"2) Authentication (30 min)- Exercise: Obtain API token (API key or OAuth2).- Show both flows; practice refreshing token.- Sample (API key):python
import os, requests
API_KEY = os.getenv("BI_API_KEY")
BASE = "https://api.bi.example.com/v1"
headers = {"Authorization": f"Bearer {API_KEY}", "Accept": "application/json"}
resp = requests.get(f"{BASE}/reports", headers=headers, timeout=10)
resp.raise_for_status()
print(resp.json()[:2])
- OAuth2 token refresh snippet (client_credentials) if applicable.Verification: successful 200 response and list of reports.3) Pagination (30 min)- Exercise: fetch full report list using cursor or page params.python
def fetch_all_reports():
url = f"{BASE}/reports"
params = {"page_size": 100}
results=[]
while url:
r = requests.get(url, headers=headers, params=params, timeout=10)
r.raise_for_status()
data = r.json()
results.extend(data["items"])
url = data.get("next") # or construct with page token
params=None
return results
Verification: count equals UI total, no duplicates.4) Filtering & Querying (30 min)- Exercise: call report export with date filters and dimensions.python
params = {"start_date":"2025-01-01","end_date":"2025-01-31","metrics":"revenue,users"}
r = requests.get(f"{BASE}/reports/123/export", headers=headers, params=params, timeout=60)
r.raise_for_status()
with open("jan_report.csv","wb") as f: f.write(r.content)
Verification: CSV contains expected date range and columns.5) Error handling & retries (20 min)- Guidance: handle 4xx vs 5xx, rate limits, idempotency.- Example:python
from time import sleep
for attempt in range(4):
r = requests.get(url, headers=headers, timeout=10)
if r.status_code == 429:
wait = int(r.headers.get("Retry-After", 2)) * (2**attempt)
sleep(wait); continue
try:
r.raise_for_status()
break
except requests.HTTPError as e:
if 500 <= r.status_code < 600 and attempt < 3: sleep(2**attempt); continue
raise
Best practices: log correlation_id from error payload, surface user-friendly messages, avoid retrying non-idempotent POSTs.6) Automation & Tests (45 min)- Exercise: write pytest tests to assert schema fields, sample sizes, and token expiry handling.- CI: run on pull request with mocked API (VCR or responses).7) Security & Governance (15 min)- Store secrets in vault/CI vars, least privilege scopes, rotate keys.Final Verification Checklist:- Able to authenticate and list reports (200)- Retrieve full paginated dataset matching UI totals- Export filtered report with correct columns and date range- Demonstrated handling 429/5xx with backoff and logging- Tests pass locally and in CIDeliverables:- Git repo with scripts, README exercises, sample .env.template, pytest tests, and Postman collection.