A CLI currency converter that fetches live exchange rates from a free API, converts between 150+ currencies, and caches rates for offline use.
Use exchangerate-api.com — free tier gives 1,500 requests/month with no API key for the open endpoint.
import requests, json, os, datetime
CACHE_FILE = 'rates_cache.json'
BASE_URL = 'https://open.er-api.com/v6/latest/USD'
def fetch_rates():
"""Fetch live rates, cache for 24 hours."""
if os.path.exists(CACHE_FILE):
with open(CACHE_FILE) as f:
cached = json.load(f)
cache_date = datetime.date.fromisoformat(cached['date'])
if cache_date == datetime.date.today():
print("Using cached rates from today.")
return cached['rates']
print("Fetching live rates...")
r = requests.get(BASE_URL, timeout=10)
data = r.json()
rates = data['rates']
with open(CACHE_FILE, 'w') as f:
json.dump({'date': str(datetime.date.today()), 'rates': rates}, f)
return rates
rates = fetch_rates()
print(f"Loaded {len(rates)} currencies.")
print(f"1 USD = {rates['INR']:.2f} INR")
print(f"1 USD = {rates['EUR']:.4f} EUR")
Fetching live rates... Loaded 162 currencies. 1 USD = 83.47 INR 1 USD = 0.9182 EUR
All rates are relative to USD — convert via USD as the intermediate.
def convert(amount, from_curr, to_curr, rates):
from_curr = from_curr.upper()
to_curr = to_curr.upper()
if from_curr not in rates:
print(f"Unknown currency: {from_curr}"); return None
if to_curr not in rates:
print(f"Unknown currency: {to_curr}"); return None
# Convert to USD first, then to target
amount_usd = amount / rates[from_curr]
amount_target = amount_usd * rates[to_curr]
return amount_target
result = convert(1000, 'INR', 'USD', rates)
print(f"₹1,000 = ${result:.2f} USD")
result2 = convert(100, 'EUR', 'GBP', rates)
print(f"€100 = £{result2:.2f} GBP")
₹1,000 = $11.98 USD €100 = £85.23 GBP
Build a menu so users can keep converting without restarting the script.
def main():
rates = fetch_rates()
print(f"\n💱 Currency Converter ({len(rates)} currencies supported)")
print("Type 'list' to see all currencies, 'quit' to exit.\n")
while True:
try:
line = input("Amount + From + To (e.g. 5000 INR USD): ").strip()
if line.lower() == 'quit': break
if line.lower() == 'list':
print(', '.join(sorted(rates.keys()))); continue
parts = line.split()
if len(parts) != 3:
print("Format: <amount> <FROM> <TO>"); continue
amount = float(parts[0])
from_curr = parts[1].upper()
to_curr = parts[2].upper()
result = convert(amount, from_curr, to_curr, rates)
if result is not None:
symbols = {'USD':'$','EUR':'€','GBP':'£','INR':'₹','JPY':'¥'}
sym = symbols.get(to_curr, to_curr + ' ')
print(f" → {sym}{result:,.4f}\n")
except (ValueError, KeyboardInterrupt):
break
main()
💱 Currency Converter (162 currencies supported) Type 'list' to see all currencies, 'quit' to exit. Amount + From + To (e.g. 5000 INR USD): 50000 INR EUR → €548.7230 Amount + From + To (e.g. 5000 INR USD): 200 GBP JPY → ¥37,842.1200
Your converter fetches live rates and caches them — it even works offline for 24 hours after the first fetch. The same convert() function can be embedded in any app that needs currency conversion.
Spotted a bug, broken code, or something that doesn't look right? Tell us what's off and we'll fix it.