HMRC exchange rates (monthly, spot, yearly average, weekly) with bundled history and exact GBP conversion
Project description
hmrc-rates
HMRC exchange rates for Python, backed by the hmrc-rates Rust crate.
The full published history ships inside the wheel, so Rates() is free and needs no network, parsing or I/O.
All money values are decimal.Decimal and conversions are exact — the library never rounds.
Install
python3 -m pip install hmrc-rates
Python ≥ 3.10. Wheels ship for Linux (glibc and musl, x86_64 and aarch64), macOS and Windows. The sdist builds anywhere with a Rust toolchain.
Quick start
import datetime
from decimal import Decimal
from hmrc_rates import YearMonth, Rates, YearEnd
rates = Rates()
# Monthly customs/VAT rate; months can be YearMonth, datetime.date, or "YYYY-MM"
rate = rates.monthly_rate("USD", YearMonth(2025, 8))
gbp = rate.to_gbp(Decimal("2500")) # exact — you choose the rounding
print(f"$2500 in Aug 2025 = £{gbp.quantize(Decimal('0.01'))}")
# Self Assessment style: the yearly average to 31 March 2025
eur = rates.average(YearEnd.march(2025)).rate("EUR")
print(f"EUR average, year to 31 Mar 2025: {eur.units_per_gbp}")
# Whole tables iterate as (Currency, Rate) pairs
table = rates.monthly(datetime.date(2025, 8, 15))
print(f"{len(table)} currencies in {table.period}")
"GBP" always resolves to the identity rate, and code lookups are case-insensitive.
Data coverage
One Rates value holds all four series HMRC has published:
| Series | Coverage | Lookup |
|---|---|---|
| Monthly customs/VAT | 2014-02 — present, no gaps | monthly_rate(code, month) |
| Spot | Dec 2010 — present, years ending 31 Mar / 31 Dec | spot(year_end) |
| Yearly average | Dec 2010 — present, years ending 31 Mar / 31 Dec | average(year_end) |
| Weekly amendments | 2014-01 — 2016-04, complete (discontinued by HMRC) | weekly(date) |
Currency codes are as published by HMRC, which is not always ISO 4217.
E.g. Ecuador appears as ECS.
Strict lookups and exceptions
A period HMRC never published is an exception, never a silently substituted older rate.
Every exception derives from HmrcRatesError (not the builtin LookupError):
UnknownCurrencyError— the code never appears in that seriesPeriodNotAvailableError— no table for that period (the message includes the available range)NotInPeriodError— the period exists but the currency is absent from itFetchError— fetching fresh rates failed
Fallback is opt-in and visible:
rate = rates.monthly_rate_or_earlier("USD", month, 2)
rate.period # reveals which month was actually used
Exactness
Amounts must be decimal.Decimal or int: floats raise TypeError because they are inexact.
Results come back as decimal.Decimal, unrounded.
Apply whatever rounding your tax context requires.
Fresh rates
Updater fetches whatever HMRC has published since this release and caches the files verbatim in the system cache directory.
refreshed() performs blocking HTTP with the GIL released.
cached() never touches the network.
from hmrc_rates import FetchError, Updater
updater = Updater()
try:
rates = updater.refreshed()
except FetchError as e:
print(f"warning: possibly stale rates: {e}")
rates = updater.cached() # offline fallback is an explicit choice
New HMRC publications also trigger a new patch release of this package automatically. So pinning the latest version is an alternative to runtime fetching.
Development
cd python
uv venv && uv pip install maturin pytest
VIRTUAL_ENV=$PWD/.venv .venv/bin/maturin develop
.venv/bin/pytest
The package is a PyO3 binding built with Maturin. The Rust sources live in the repository root.
Licence
MIT.
Disclaimer
This project is not affiliated with, endorsed by, or maintained by HMRC. Only the underlying rate data comes from HMRC.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hmrc_rates-0.3.1.tar.gz.
File metadata
- Download URL: hmrc_rates-0.3.1.tar.gz
- Upload date:
- Size: 682.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3fef6e4252b56f3c905ce007a0aeba6ce5ad5a2b77e73533ada3cf652cab467e
|
|
| MD5 |
908b6d0733ab71b8f47296dfcb62df74
|
|
| BLAKE2b-256 |
546c2d956ba61a2ade7fbad0a992620e1aa8181407bdbd05806d5b40a9074f9b
|
Provenance
The following attestation bundles were made for hmrc_rates-0.3.1.tar.gz:
Publisher:
python.yaml on velikodniy/hmrc-rates
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hmrc_rates-0.3.1.tar.gz -
Subject digest:
3fef6e4252b56f3c905ce007a0aeba6ce5ad5a2b77e73533ada3cf652cab467e - Sigstore transparency entry: 2129893037
- Sigstore integration time:
-
Permalink:
velikodniy/hmrc-rates@1820c9341dca46ef39fc42c65b7b0e2eecb08abf -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/velikodniy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python.yaml@1820c9341dca46ef39fc42c65b7b0e2eecb08abf -
Trigger Event:
push
-
Statement type:
File details
Details for the file hmrc_rates-0.3.1-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: hmrc_rates-0.3.1-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 1.4 MB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
01f70ded683a1e004a56720bfe1e71e6d31f1d1bf8c29529822c8f9857fa145c
|
|
| MD5 |
4a2c33d3458b3f6997f087f76601ee22
|
|
| BLAKE2b-256 |
c9bda6d3e38084975cffd39a889c73d581e387abdd9b5bb1377404aa5ad305a4
|
Provenance
The following attestation bundles were made for hmrc_rates-0.3.1-cp310-abi3-win_amd64.whl:
Publisher:
python.yaml on velikodniy/hmrc-rates
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hmrc_rates-0.3.1-cp310-abi3-win_amd64.whl -
Subject digest:
01f70ded683a1e004a56720bfe1e71e6d31f1d1bf8c29529822c8f9857fa145c - Sigstore transparency entry: 2129893057
- Sigstore integration time:
-
Permalink:
velikodniy/hmrc-rates@1820c9341dca46ef39fc42c65b7b0e2eecb08abf -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/velikodniy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python.yaml@1820c9341dca46ef39fc42c65b7b0e2eecb08abf -
Trigger Event:
push
-
Statement type:
File details
Details for the file hmrc_rates-0.3.1-cp310-abi3-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: hmrc_rates-0.3.1-cp310-abi3-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 1.8 MB
- Tags: CPython 3.10+, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
68480b39a93bfc3b2b287035a9a117831af1b8936987d60625e816051d086e4e
|
|
| MD5 |
feb7ddd5c091bd7e8ff9409650966596
|
|
| BLAKE2b-256 |
de4739c066e5de602db9792beba00bd34632662706437f243cc1e24944a94f93
|
Provenance
The following attestation bundles were made for hmrc_rates-0.3.1-cp310-abi3-musllinux_1_2_x86_64.whl:
Publisher:
python.yaml on velikodniy/hmrc-rates
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hmrc_rates-0.3.1-cp310-abi3-musllinux_1_2_x86_64.whl -
Subject digest:
68480b39a93bfc3b2b287035a9a117831af1b8936987d60625e816051d086e4e - Sigstore transparency entry: 2129893084
- Sigstore integration time:
-
Permalink:
velikodniy/hmrc-rates@1820c9341dca46ef39fc42c65b7b0e2eecb08abf -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/velikodniy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python.yaml@1820c9341dca46ef39fc42c65b7b0e2eecb08abf -
Trigger Event:
push
-
Statement type:
File details
Details for the file hmrc_rates-0.3.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: hmrc_rates-0.3.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.5 MB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c86442f62173e5f41b3769e0e1157200936a8f74b288b3d21f90f59dc94fa45e
|
|
| MD5 |
68a22c7b921561917ad519c94f393cb8
|
|
| BLAKE2b-256 |
42ba0cc7ed40327c3b33a319e080fde01606df6feba6e70e3a56601edcf7c083
|
Provenance
The following attestation bundles were made for hmrc_rates-0.3.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
python.yaml on velikodniy/hmrc-rates
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hmrc_rates-0.3.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
c86442f62173e5f41b3769e0e1157200936a8f74b288b3d21f90f59dc94fa45e - Sigstore transparency entry: 2129893117
- Sigstore integration time:
-
Permalink:
velikodniy/hmrc-rates@1820c9341dca46ef39fc42c65b7b0e2eecb08abf -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/velikodniy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python.yaml@1820c9341dca46ef39fc42c65b7b0e2eecb08abf -
Trigger Event:
push
-
Statement type:
File details
Details for the file hmrc_rates-0.3.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: hmrc_rates-0.3.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.5 MB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
26cfc5b031ca3e25a879f8a29648dd006488374c9c76d6797686db50a0d42830
|
|
| MD5 |
ea909263732ce227335717e056191dda
|
|
| BLAKE2b-256 |
0282122bccb2c0543c355c648e02633cb82002a2b2879f9e3ab070962458192f
|
Provenance
The following attestation bundles were made for hmrc_rates-0.3.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
python.yaml on velikodniy/hmrc-rates
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hmrc_rates-0.3.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
26cfc5b031ca3e25a879f8a29648dd006488374c9c76d6797686db50a0d42830 - Sigstore transparency entry: 2129893075
- Sigstore integration time:
-
Permalink:
velikodniy/hmrc-rates@1820c9341dca46ef39fc42c65b7b0e2eecb08abf -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/velikodniy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python.yaml@1820c9341dca46ef39fc42c65b7b0e2eecb08abf -
Trigger Event:
push
-
Statement type:
File details
Details for the file hmrc_rates-0.3.1-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.
File metadata
- Download URL: hmrc_rates-0.3.1-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
- Upload date:
- Size: 2.8 MB
- Tags: CPython 3.10+, macOS 10.12+ universal2 (ARM64, x86-64), macOS 10.12+ x86-64, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0d1939d3e7d68338f807bef24d5436a02f6c55cbd4f7e96beb052a8deaf18c6d
|
|
| MD5 |
be8763d7ddd217f8cfa98f1826679f31
|
|
| BLAKE2b-256 |
3b36ff5460cfa8e683f20eacde3b274c79240f28a10f13794ddba70781cd0ff0
|
Provenance
The following attestation bundles were made for hmrc_rates-0.3.1-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:
Publisher:
python.yaml on velikodniy/hmrc-rates
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hmrc_rates-0.3.1-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl -
Subject digest:
0d1939d3e7d68338f807bef24d5436a02f6c55cbd4f7e96beb052a8deaf18c6d - Sigstore transparency entry: 2129893099
- Sigstore integration time:
-
Permalink:
velikodniy/hmrc-rates@1820c9341dca46ef39fc42c65b7b0e2eecb08abf -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/velikodniy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python.yaml@1820c9341dca46ef39fc42c65b7b0e2eecb08abf -
Trigger Event:
push
-
Statement type: