Skip to main content

exrate

A zero-dependency command-line client for the Frankfurter v2 foreign-exchange API. Daily reference rates from 84 central banks, 201 currencies, back to 1948. No API key, no login, no rate caps for normal use.

It's a single Python file (exrate.py, stdlib only) — runs anywhere Python 3.8+ exists. Every subcommand maps 1:1 to the Frankfurter OpenAPI spec, and every subcommand accepts --json for machine-readable output, which also makes it pleasant to drive from scripts and AI agents.

Install

From PyPI (recommended):

pipx install exrate     # isolated, puts `exrate` on your PATH
# or
pip install exrate

From source (symlink install for hacking on it):

git clone https://github.com/ekinertac/exrate.git
cd exrate
./install.sh        # symlinks exrate.py -> ~/.local/bin/exrate
exrate --help

install.sh symlinks (not copies) the script, so edits take effect with no reinstall. It installs into ~/.local/bin; make sure that's on your PATH.

Usage

exrate rate EUR USD                              # latest single pair
exrate rate EUR USD --date 2020-03-15            # historical
exrate convert 100 USD JPY                       # convert an amount (client-side)
exrate rates --base USD --quotes EUR,GBP,JPY     # several pairs at once
exrate rates --from 2026-01-01 --quotes USD      # daily time series
exrate rates --from 2026-01-01 --group month     # downsample to monthly
exrate rates --from 2026-01-01 --quotes USD --csv  # native CSV
exrate currencies                                # list currency codes
exrate currencies --all                          # include legacy currencies
exrate currency AED                              # one currency's details + peg
exrate providers                                 # data sources (central banks)

Add --json to any command for raw API JSON (numbers stay JSON numbers, not strings), handy for jq pipelines:

exrate currencies --json | jq -r '.[].iso_code'
exrate providers  --json | jq -r '.[].key'

Run exrate <subcommand> --help for that command's modes, fields, and examples.

Commands

Command Endpoint Purpose
rate BASE QUOTE GET /rate/{base}/{quote} One pair, latest or historical
rates GET /rates Many rates: latest, a date, or a time series
convert AMOUNT FROM TO (client-side) Multiply amount by the pair rate
currencies GET /currencies List supported currency codes
currency CODE GET /currency/{code} One currency's details + peg metadata
providers GET /providers Data providers (central banks) and their keys

Conventions

  • Currency codes are ISO 4217, 3 letters, case-insensitive (eur == EUR).
  • Dates are YYYY-MM-DD. Weekends/holidays return the last published rate.
  • Default base is EUR. The base is the "1 unit" side; the rate says how many quote units equal 1 base unit.
  • Providers: rates are blended across providers by default. Pass --providers ECB to pin a single official source.
  • Conversion is client-side — the API has no conversion endpoint, so convert fetches the pair rate and multiplies (matching the official docs' approach).

Exit codes

Code Meaning
0 Success
1 API or network error (message on stderr, e.g. unknown currency)
2 Bad usage / invalid arguments

Releasing

Versions are single-sourced from __version__ in exrate.py. To cut a release:

  1. Bump __version__ in exrate.py.
  2. Commit and tag: git tag v1.2.3 && git push --tags.
  3. On GitHub: Releases → Draft a new release, pick the tag, Publish.

Publishing a GitHub Release triggers .github/workflows/publish.yml, which builds the sdist + wheel and uploads them to PyPI via Trusted Publishing (OIDC, no stored tokens). One-time PyPI setup before the first Actions run:

PyPI → Your projects / PublishingAdd a pending publisher · Owner: ekinertac · Repository: exrate · Workflow: publish.yml · Environment: pypi

To build/publish manually instead:

pipx run build                 # -> dist/*.tar.gz, dist/*.whl
pipx run twine check dist/*
pipx run twine upload dist/*   # prompts for a PyPI API token

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

exrate-1.0.1.tar.gz (9.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

exrate-1.0.1-py3-none-any.whl (10.5 kB view details)

Uploaded Python 3

File details

Details for the file exrate-1.0.1.tar.gz.

File metadata

  • Download URL: exrate-1.0.1.tar.gz
  • Upload date:
  • Size: 9.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for exrate-1.0.1.tar.gz
Algorithm Hash digest
SHA256 6c21282ef95ede5650b8b4863fe3853bf8841c6185d9cbbd9aa9a4697d213fc6
MD5 1867294f5b196d6766a6560e7373e23d
BLAKE2b-256 491a72087db29a89e0e947d1c083b4dd600e04ec33d955a4559cd64ad87911cb

See more details on using hashes here.

Provenance

The following attestation bundles were made for exrate-1.0.1.tar.gz:

Publisher: publish.yml on ekinertac/exrate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file exrate-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: exrate-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 10.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for exrate-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 21abfe9b9f8b880bf91aba36fb50141ee318bcea23793abc516998004a0ef8a6
MD5 92db10b7478a6e2d40d250a5402e0c4e
BLAKE2b-256 65de8b4db811be75efb1873e49463c0929b0a84564ba797d85bb63e759364ae7

See more details on using hashes here.

Provenance

The following attestation bundles were made for exrate-1.0.1-py3-none-any.whl:

Publisher: publish.yml on ekinertac/exrate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 files

1.0.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page