Tutorial · Python

Currency conversion in Python

Get live and historical exchange rates in Python, convert amounts correctly with Decimal and add rates to a pandas DataFrame.

Updated October 1, 2026 · 2 min read

Latest rates with requests

import os
import requests

API_KEY = os.environ["CURRENCYAPI_KEY"]

def latest_rates(base="USD", currencies=("EUR", "GBP", "JPY")):
    res = requests.get(
        "https://api.currencyapi.com/v3/latest",
        params={"base_currency": base, "currencies": ",".join(currencies)},
        headers={"apikey": API_KEY},
        timeout=10,
    )
    res.raise_for_status()
    return {code: item["value"] for code, item in res.json()["data"].items()}

print(latest_rates())
# {'EUR': 0.8828, 'GBP': 0.7556, 'JPY': 157.98}

Converting amounts correctly

from decimal import Decimal, ROUND_HALF_UP

def convert(amount: str, rate: float, decimals: int = 2) -> Decimal:
    result = Decimal(amount) * Decimal(str(rate))
    return result.quantize(Decimal(1).scaleb(-decimals), rounding=ROUND_HALF_UP)

rates = latest_rates("USD", ["EUR"])
print(convert("199.99", rates["EUR"]))  # e.g. Decimal('176.56')

Use decimals=0 for currencies without minor units such as JPY or KRW; the currency pages list the decimals of every currency.

Historical rates

def rate_on(date: str, base: str, quote: str) -> float:
    res = requests.get(
        "https://api.currencyapi.com/v3/historical",
        params={"date": date, "base_currency": base, "currencies": quote},
        headers={"apikey": API_KEY},
        timeout=10,
    )
    res.raise_for_status()
    return res.json()["data"][quote]["value"]

print(rate_on("2024-03-15", "USD", "EUR"))

Cache the rates

Rates do not change between two requests a second apart. Cache the latest rates for a few minutes and historical rates forever, for example with functools.lru_cache for historical dates:

from functools import lru_cache

@lru_cache(maxsize=4096)
def cached_rate_on(date, base, quote):
    return rate_on(date, base, quote)

pandas: convert a column of transactions

import pandas as pd

df = pd.DataFrame({"date": ["2024-03-15", "2024-06-03"], "amount_usd": [120.0, 89.5]})
df["rate_eur"] = [cached_rate_on(d, "USD", "EUR") for d in df["date"]]
df["amount_eur"] = (df["amount_usd"] * df["rate_eur"]).round(2)

Get a free API key with 300 requests per month on the pricing page.

Frequently asked questions

Is there a Python library for currency conversion?

Packages such as forex-python wrap free data sources, but their sources change or disappear. Calling an exchange rate API with requests is a few lines of code and gives you control over update frequency and history.

Should I use float for money in Python?

No. Use decimal.Decimal for amounts and round with quantize to the currency's minor units, otherwise you get results like 0.1 + 0.2 = 0.30000000000000004.

Exchange rate API

Get these rates in your app

currencyapi delivers real-time and historical exchange rates for 170+ currencies, crypto and metals as JSON, updated as often as every 60 seconds.

300 free requests every month. No credit card required.

GET https://api.currencyapi.com/v3/latest?base_currency=USD&currencies=EUR,GBP,JPY

{
  "meta": { "last_updated_at": "2026-09-30T23:59:59Z" },
  "data": {
    "EUR": { "code": "EUR", "value": 0.8828 },
    "GBP": { "code": "GBP", "value": 0.7556 },
    "JPY": { "code": "JPY", "value": 157.98 }
  }
}

Keep reading

Start using our Currency API for free today!

Get 300 requests / month for free