Integration guide

Add currency exchange rates and conversion to Flask

Call the API from a Flask route and cache the latest response in memory until nextUpdateAt. Keep credentials in server environment.

1. Get a free API key

Sign up at https://currencyexchangerate-api.com/auth/login, then create a key under API keys in the console. The free plan includes 3,000 requests per month with no credit card. Store the secret as CXR_API_KEY in server-side environment configuration; never expose it in browser code.

.env

shell
CXR_API_KEY=cxr_your_secret_key

2. Create a reusable client and cache rates

Use the standard HTTP client. Cache every /latest response until nextUpdateAt: rates change at most once by then, and reusing the response saves quota. The helper also exposes /convert.

rates.py

Python
import osimport timefrom datetime import datetime import requests API_BASE_URL = 'https://api.currencyexchangerate-api.com/api/v1'HEADERS = {'Authorization': 'Bearer ' + os.environ['CXR_API_KEY']}_cache = {}  def latest(base='USD', symbols='EUR,GBP'):    key = (base, symbols)    if key in _cache and time.time() < _cache[key][0]:        return _cache[key][1]    response = requests.get(        API_BASE_URL + '/latest',        params={'base': base, 'symbols': symbols},        headers=HEADERS,    )    response.raise_for_status()    data = response.json()    next_update = data['nextUpdateAt'].replace('Z', '+00:00')    until = datetime.fromisoformat(next_update).timestamp()    _cache[key] = (until, data)    return data  def convert(source, target, amount):    response = requests.get(        API_BASE_URL + '/convert',        params={'from': source, 'to': target, 'amount': amount},        headers=HEADERS,    )    response.raise_for_status()    return response.json()

3. Use it in Flask

Call the helper from a server route, controller, view, command, or script. Format converted values for the user’s locale.

app.py

Python
from flask import Flask, jsonify, request from rates import convert app = Flask(__name__)  @app.get('/convert')def conversion():    data = convert(        request.args.get('from', 'EUR'),        request.args.get('to', 'GBP'),        request.args.get('amount', 100),    )    data['formatted'] = f"{data['result']:,.2f} {data['to']}"    return jsonify(data)

4. Handle API errors

A 401 means the key is invalid. A 429 can mean a rate limit or quota limit; read Retry-After in seconds before retrying. Other errors use application/problem+json.

errors.py

Python
import requests from rates import convert try:    result = convert('EUR', 'GBP', 100)except requests.HTTPError as error:    response = error.response    if response.status_code == 401:        raise RuntimeError('Check CXR_API_KEY') from error    if response.status_code == 429:        retry_after = response.headers.get('Retry-After', '?')        raise RuntimeError(f'Retry after {retry_after} seconds') from error    detail = response.json().get('detail', 'Rates API error')    raise RuntimeError(detail) from error

5. Format the amount for display

Use locale-aware currency formatting instead of adding a symbol manually.

format.py

Python
# pip install babelfrom babel.numbers import format_currency print(format_currency(85.249105, 'EUR', locale='en_GB'))