Working with APIs
APIs connect your Python scripts to external data: weather forecasts, stock prices, CRM systems, payment gateways. Business analysts use APIs to pull live data into reports, sync systems, and automate workflows. Master APIs and you unlock thousands of data sources.
Estimated reading time: 25–30 minutes
API Basics
- GET → retrieve data from server
- POST → send data to server
- JSON → standard data format for APIs
- Status codes → 200 OK, 404 Not Found, 500 Error
Great for: fetching live data, integrations
Best Practices
- Authentication → API keys, tokens for security
- Error handling → check status codes, handle timeouts
- Rate limits → respect API usage limits
- Caching → save responses to reduce API calls
Great for: production-ready integrations
Making GET Requests
GET requests retrieve data from an API endpoint.
import requests
# Simple GET request
response = requests.get('https://api.example.com/users')
print(response.status_code) # 200 = success
# Parse JSON response
data = response.json()
print(data)
# GET with query parameters
params = {'page': 1, 'limit': 10}
response = requests.get('https://api.example.com/users', params=params)
print(response.url) # shows full URL with paramsMaking POST Requests
POST requests send data to create or update resources.
import requests
# POST with JSON data
payload = {
'name': 'Ana Garcia',
'email': 'ana@company.com',
'role': 'analyst'
}
response = requests.post(
'https://api.example.com/users',
json=payload
)
print(response.status_code) # 201 = created
print(response.json()) # server responseAuthentication with API Keys
Most APIs require authentication via API keys or tokens.
import requests
# API key in headers
headers = {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
}
response = requests.get(
'https://api.example.com/data',
headers=headers
)
# API key in query params (less secure)
params = {'api_key': 'YOUR_API_KEY'}
response = requests.get('https://api.example.com/data', params=params)Error Handling
Always handle errors: network issues, invalid responses, rate limits.
import requests
try:
response = requests.get(
'https://api.example.com/data',
timeout=5 # 5 second timeout
)
response.raise_for_status() # raises error for 4xx/5xx
data = response.json()
print("Success:", data)
except requests.exceptions.Timeout:
print("Error: Request timed out")
except requests.exceptions.HTTPError as e:
print("HTTP Error:", e)
except requests.exceptions.RequestException as e:
print("Error:", e)Pagination
APIs often return data in pages. Loop through all pages to get complete data.
import requests
def fetch_all_pages(base_url):
all_data = []
page = 1
while True:
response = requests.get(base_url, params={'page': page, 'limit': 100})
response.raise_for_status()
data = response.json()
if not data: # no more data
break
all_data.extend(data)
page += 1
return all_data
users = fetch_all_pages('https://api.example.com/users')
print("Total users:", len(users))Cornerstone Project — Currency Exchange Rate Monitor (step-by-step)
Build a tool that fetches live currency exchange rates from an API, tracks changes over time, alerts on significant moves, and exports to CSV. This is useful for finance teams, international businesses, or personal investing.
Step 1 — Choose a free API
Use exchangerate-api.com (free tier available).
import requests
# Free API endpoint (replace with your API key)
API_KEY = "your_api_key_here"
BASE_URL = "https://v6.exchangerate-api.com/v6/" + API_KEY
def get_exchange_rates(base_currency="USD"):
url = BASE_URL + "/latest/" + base_currency
response = requests.get(url)
response.raise_for_status()
return response.json()
# Test it
data = get_exchange_rates("USD")
print("Base:", data['base_code'])
print("Rates:", data['conversion_rates'])Step 2 — Fetch specific currency pairs
Get rates for currencies you care about.
def get_rate(from_currency, to_currency):
data = get_exchange_rates(from_currency)
rates = data['conversion_rates']
return rates.get(to_currency)
# Example: USD to EUR
usd_to_eur = get_rate("USD", "EUR")
print("1 USD =", usd_to_eur, "EUR")
# Multiple pairs
pairs = [("USD", "EUR"), ("USD", "GBP"), ("USD", "JPY")]
for from_curr, to_curr in pairs:
rate = get_rate(from_curr, to_curr)
print(from_curr, "to", to_curr, ":", rate)Step 3 — Track rates over time
Store historical data to detect trends.
from datetime import datetime
import json
def save_rate_snapshot(base_currency, currencies):
data = get_exchange_rates(base_currency)
snapshot = {
'timestamp': datetime.now().isoformat(),
'base': base_currency,
'rates': {curr: data['conversion_rates'][curr] for curr in currencies}
}
# Append to file
with open('rate_history.json', 'a') as f:
f.write(json.dumps(snapshot) + '\n')
return snapshot
# Save snapshot
currencies = ['EUR', 'GBP', 'JPY']
snapshot = save_rate_snapshot('USD', currencies)
print("Saved:", snapshot)Step 4 — Calculate rate changes
Compare current rate to previous snapshot.
def load_rate_history():
history = []
try:
with open('rate_history.json', 'r') as f:
for line in f:
history.append(json.loads(line))
except FileNotFoundError:
pass
return history
def calculate_changes(current_snapshot):
history = load_rate_history()
if len(history) < 2:
return {}
previous = history[-2]
changes = {}
for currency, rate in current_snapshot['rates'].items():
prev_rate = previous['rates'].get(currency)
if prev_rate:
change_pct = ((rate - prev_rate) / prev_rate) * 100
changes[currency] = round(change_pct, 2)
return changes
# Get changes
snapshot = save_rate_snapshot('USD', ['EUR', 'GBP', 'JPY'])
changes = calculate_changes(snapshot)
print("Changes:", changes)Step 5 — Alert on significant moves
Flag currencies that moved more than threshold.
def check_alerts(changes, threshold=1.0):
alerts = []
for currency, change_pct in changes.items():
if abs(change_pct) >= threshold:
direction = "up" if change_pct > 0 else "down"
alerts.append({
'currency': currency,
'change': change_pct,
'direction': direction
})
return alerts
# Check for alerts
alerts = check_alerts(changes, threshold=0.5)
if alerts:
print("ALERTS:")
for alert in alerts:
print(" •", alert['currency'], "moved", alert['change'], "%", alert['direction'])
else:
print("No significant moves")Step 6 — Export to CSV
Create report for stakeholders.
import csv
def export_to_csv(filename='exchange_rates.csv'):
history = load_rate_history()
if not history:
return
# Get all currencies
currencies = set()
for snapshot in history:
currencies.update(snapshot['rates'].keys())
# Write CSV
with open(filename, 'w', newline='') as f:
fieldnames = ['timestamp', 'base'] + sorted(currencies)
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
for snapshot in history:
row = {
'timestamp': snapshot['timestamp'],
'base': snapshot['base']
}
row.update(snapshot['rates'])
writer.writerow(row)
print("Exported to", filename)
export_to_csv()Step 7 — Put it all together
Create monitoring script that runs periodically.
def monitor_exchange_rates():
base = 'USD'
currencies = ['EUR', 'GBP', 'JPY', 'CAD', 'AUD']
# Fetch current rates
snapshot = save_rate_snapshot(base, currencies)
print("Fetched rates for", base)
# Calculate changes
changes = calculate_changes(snapshot)
if changes:
print("Changes since last check:")
for curr, change in changes.items():
print(" •", curr, ":", change, "%")
# Check alerts
alerts = check_alerts(changes, threshold=0.5)
if alerts:
print("\nALERTS:")
for alert in alerts:
print(" • WARNING:", alert['currency'], "moved", alert['change'], "%")
# Export
export_to_csv()
print("\nMonitoring complete!")
# Run it (schedule with cron or Task Scheduler)
monitor_exchange_rates()How this helps at work
- Live data → always current, no manual updates
- Automated alerts → catch significant moves immediately
- Historical tracking → analyze trends over time
- Reusable pattern → adapt for stock prices, weather, any API
Key Takeaways
- GET requests → retrieve data from APIs
- POST requests → send data to APIs
- Authentication → API keys in headers or params
- Error handling → timeouts, HTTP errors, network issues
- Pagination → loop through pages for complete data
- Cornerstone → currency monitor tracks live exchange rates
Next Steps
You have mastered API basics. Next, explore authentication methods (OAuth, JWT), or dive intobuilding your own API with Flask or FastAPI.