Integration guide

Add currency exchange rates and conversion to Django

Use Django views and its cache framework to retain latest rates until nextUpdateAt. Keep the key in server environment settings.

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 osfrom datetime import datetime, timezone import requestsfrom django.core.cache import cache API_BASE_URL = 'https://api.currencyexchangerate-api.com/api/v1'HEADERS = {'Authorization': 'Bearer ' + os.environ['CXR_API_KEY']}  def latest(base='USD', symbols='EUR,GBP'):    key = f'rates:{base}:{symbols}'    data = cache.get(key)    if data:        return data    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)    seconds = max(1, int((until - datetime.now(timezone.utc)).total_seconds()))    cache.set(key, data, seconds)    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 Django

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

views.py

Python
from django.http import JsonResponse from .rates import convert  def conversion(request):    data = convert(        request.GET.get('from', 'EUR'),        request.GET.get('to', 'GBP'),        request.GET.get('amount', 100),    )    data['formatted'] = f"{data['result']:,.2f} {data['to']}"    return JsonResponse(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'))