How to Get Live Exchange Rates in Python: A Developer's Guide
If you are building a Python application that handles money across borders — whether it is an e-commerce platform, a fintech dashboard, or a data pipeline — you need reliable, real-time exchange rates. This guide covers two practical approaches to fetching live currency rates in Python, plus production-ready patterns for caching, error handling, and framework integration.
Why You Need Live Exchange Rates in Python
Hardcoding exchange rates is a non-starter. Rates fluctuate constantly, and even a small drift can compound into significant errors at scale. Here are the most common scenarios where live rates are essential:
- E-commerce checkout — Converting product prices for international customers in real time.
- Financial reporting — Generating accurate multi-currency balance sheets and P&L statements.
- Data analysis — Normalizing revenue data across regions for dashboards and forecasts.
- Payment processing — Calculating settlement amounts between currencies at the point of transaction.
- Travel applications — Showing users real-time conversion estimates before they spend.
The right approach is to pull rates from a reliable API, cache them sensibly, and handle failures gracefully. Let's look at how.
Option 1: Using the Requests Library (Raw HTTP)
The most straightforward way is to call an exchange rate REST API directly with Python's requests library. AllRatesToday provides a clean JSON API that supports 160+ currencies with rates updated every 60 seconds.
Installation
pip install requests Fetching the Latest Rates
import requests
API_KEY = "your_api_key_here"
BASE_URL = "https://api.allratestoday.com/v1"
def get_latest_rates(base_currency="USD"):
"""Fetch the latest exchange rates for a given base currency."""
response = requests.get(
f"{BASE_URL}/latest",
params={"base": base_currency},
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=10,
)
response.raise_for_status()
data = response.json()
return data["rates"]
rates = get_latest_rates("USD")
print(f"USD to EUR: {rates['EUR']}")
print(f"USD to GBP: {rates['GBP']}")
print(f"USD to JPY: {rates['JPY']}") Converting Between Currencies
def convert_currency(amount, from_currency, to_currency):
"""Convert an amount from one currency to another."""
rates = get_latest_rates(from_currency)
if to_currency not in rates:
raise ValueError(f"Unsupported currency: {to_currency}")
return round(amount * rates[to_currency], 2)
# Convert 100 USD to EUR
result = convert_currency(100, "USD", "EUR")
print(f"100 USD = {result} EUR") This approach gives you full control over the HTTP request, headers, and response parsing. It works well when you want to keep dependencies minimal or need to customize the request behavior.
Option 2: Using the AllRatesToday Python SDK
For a cleaner developer experience, the AllRatesToday Python SDK wraps the API with a Pythonic interface, built-in error handling, and automatic retries.
Installation
pip install allratestoday Basic Usage
from allratestoday import AllRatesToday
client = AllRatesToday("your_api_key_here")
# Get latest rates
rates = client.get_rates(base="USD")
print(f"USD to EUR: {rates['EUR']}")
# Convert directly
result = client.convert(amount=250, from_currency="GBP", to_currency="JPY")
print(f"250 GBP = {result} JPY") Fetching Historical Rates
# Get rates for a specific date
historical = client.get_rates(base="EUR", date="2026-01-15")
print(f"EUR to USD on Jan 15: {historical['USD']}") Tip: The SDK handles authentication, request formatting, and response parsing automatically. It is the recommended approach for most Python projects.
Comparing the Two Approaches
| Feature | requests library | AllRatesToday SDK |
|---|---|---|
| Setup complexity | Manual headers, URL construction | One-line initialization |
| Error handling | Manual status code checks | Built-in exceptions |
| Retries | Must implement yourself | Automatic with backoff |
| Dependencies | Only requests | allratestoday package |
| Best for | Maximum control | Fastest development |
Caching Rates to Minimize API Calls
Fetching rates on every request is wasteful and will burn through your API quota. Exchange rates do not change every millisecond — a smart cache with a short TTL is the right pattern.
Simple In-Memory Cache
import time
from allratestoday import AllRatesToday
client = AllRatesToday("your_api_key_here")
_cache = {}
CACHE_TTL = 300 # 5 minutes
def get_cached_rates(base="USD"):
"""Return cached rates if fresh, otherwise fetch new ones."""
now = time.time()
cache_key = f"rates_{base}"
if cache_key in _cache:
cached_data, timestamp = _cache[cache_key]
if now - timestamp < CACHE_TTL:
return cached_data
rates = client.get_rates(base=base)
_cache[cache_key] = (rates, now)
return rates Redis Cache for Multi-Instance Deployments
If you are running multiple server instances behind a load balancer, an in-memory dictionary will not be shared between them. Use Redis instead:
import json
import redis
from allratestoday import AllRatesToday
r = redis.Redis(host="localhost", port=6379, db=0)
client = AllRatesToday("your_api_key_here")
def get_rates_with_redis(base="USD", ttl=300):
"""Fetch rates with Redis caching."""
cache_key = f"exchange_rates:{base}"
cached = r.get(cache_key)
if cached:
return json.loads(cached)
rates = client.get_rates(base=base)
r.setex(cache_key, ttl, json.dumps(rates))
return rates Choosing a TTL: 60 seconds for near-real-time apps. 5 minutes for e-commerce. Up to 24 hours for accounting and reporting. Match your TTL to how sensitive your application is to stale data.
Handling Errors and Edge Cases
Production code needs to handle network timeouts, invalid API keys, rate limits, and unexpected responses. Here is a robust pattern using the requests library:
import time
import requests
from requests.exceptions import HTTPError, Timeout, ConnectionError
API_KEY = "your_api_key_here"
BASE_URL = "https://api.allratestoday.com/v1"
def get_rates_safe(base="USD", retries=3):
"""Fetch rates with retry logic and proper error handling."""
for attempt in range(retries):
try:
response = requests.get(
f"{BASE_URL}/latest",
params={"base": base},
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=10,
)
if response.status_code == 429:
wait = int(response.headers.get("Retry-After", 60))
print(f"Rate limited. Retrying in {wait}s...")
time.sleep(wait)
continue
response.raise_for_status()
return response.json()["rates"]
except Timeout:
print(f"Timeout on attempt {attempt + 1}/{retries}")
except ConnectionError:
print(f"Connection error on attempt {attempt + 1}/{retries}")
except HTTPError as e:
if e.response.status_code == 401:
raise ValueError("Invalid API key") from e
raise
raise RuntimeError("Failed to fetch rates after all retries") Key things to handle in production:
- HTTP 429 (Too Many Requests) — Respect the
Retry-Afterheader and back off. - Timeouts — Always set a
timeoutparameter. Never let requests hang indefinitely. - Invalid API keys (401) — Fail fast and surface a clear error message.
- Network failures — Retry with backoff, then fall back to cached data if available.
Never skip timeouts. A missing timeout parameter on requests.get() can hang your entire application if the upstream API is slow to respond.
Real-World Use Cases
Flask Integration
Add a currency conversion endpoint to any Flask application in minutes:
from flask import Flask, jsonify, request
from allratestoday import AllRatesToday
app = Flask(__name__)
client = AllRatesToday("your_api_key_here")
@app.route("/api/convert")
def convert():
amount = float(request.args.get("amount", 1))
from_curr = request.args.get("from", "USD")
to_curr = request.args.get("to", "EUR")
result = client.convert(
amount=amount,
from_currency=from_curr,
to_currency=to_curr,
)
return jsonify({
"result": result,
"from": from_curr,
"to": to_curr
}) Django View
The same pattern works in Django with a function-based or class-based view:
from django.http import JsonResponse
from allratestoday import AllRatesToday
client = AllRatesToday("your_api_key_here")
def convert_view(request):
amount = float(request.GET.get("amount", 1))
from_curr = request.GET.get("from", "USD")
to_curr = request.GET.get("to", "EUR")
result = client.convert(
amount=amount,
from_currency=from_curr,
to_currency=to_curr,
)
return JsonResponse({
"result": result,
"from": from_curr,
"to": to_curr
}) Data Analysis with Pandas
Normalize multi-currency revenue data into a single base currency for analysis:
import pandas as pd
from allratestoday import AllRatesToday
client = AllRatesToday("your_api_key_here")
rates = client.get_rates(base="USD")
# Convert a DataFrame column from local currencies to USD
df = pd.DataFrame({
"revenue": [1000, 2500, 800, 3200],
"currency": ["EUR", "GBP", "JPY", "CAD"],
})
df["usd_amount"] = df.apply(
lambda row: round(row["revenue"] / rates[row["currency"]], 2),
axis=1,
)
print(df) Performance Tips
- Cache aggressively. A 5-minute cache eliminates 99% of redundant API calls without meaningful data staleness for most applications.
- Batch your requests. Fetch all rates for a base currency in one call rather than making separate calls for each currency pair.
- Use connection pooling. If you use
requestsdirectly, create aSessionobject to reuse TCP connections:
session = requests.Session()
session.headers.update({"Authorization": f"Bearer {API_KEY}"})
# Reuse session for all API calls — avoids TCP handshake overhead - Store your API key securely. Use environment variables or a secrets manager — never hardcode keys in source files:
import os
API_KEY = os.environ["ALLRATESTODAY_API_KEY"] - Set timeouts on every request. A missing timeout can hang your entire application if the API is slow to respond.
- Log API response times. Monitor latency in production so you can spot degradation before it impacts users.
Frequently Asked Questions
What is the best Python library for exchange rates?
The AllRatesToday Python SDK (pip install allratestoday) provides the simplest interface for fetching real-time exchange rates. Alternatively, you can use the requests library to call any exchange rate REST API directly.
How do I get real-time exchange rates in Python for free?
Sign up for a free API key at AllRatesToday (no credit card required), then use pip install allratestoday or the requests library to fetch rates updated every 60 seconds for 160+ currencies.
Can I use exchange rate APIs in Django or Flask?
Yes. Exchange rate APIs work with any Python web framework. Fetch rates server-side using the requests library or an SDK, cache them to reduce API calls, and serve the converted amounts to your frontend.
Get Started with Python Exchange Rates
Free API key, official Python SDK, 160+ currencies updated every 60 seconds.
Get Your Free API Key