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 / Publishing → Add 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

Metadata

Release files for exrate 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for exrate 1.0.1
File Size Uploaded
exrate-1.0.1.tar.gz 9.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for exrate 1.0.1
File Interpreter ABI Platform
exrate-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 20.2 kB

Release files / exrate-1.0.1.tar.gz

Download URL exrate-1.0.1.tar.gz
Size 9.7 kB
Tags Source
SHA-256 checksum
How to use checksums
6c21282ef95ede5650b8b4863fe3853bf8841c6185d9cbbd9aa9a4697d213fc6
BLAKE2b-256 checksum
How to use checksums
491a72087db29a89e0e947d1c083b4dd600e04ec33d955a4559cd64ad87911cb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 23, 2026.

Transparency log

Release files / exrate-1.0.1-py3-none-any.whl

Download URL exrate-1.0.1-py3-none-any.whl
Size 10.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
21abfe9b9f8b880bf91aba36fb50141ee318bcea23793abc516998004a0ef8a6
BLAKE2b-256 checksum
How to use checksums
65de8b4db811be75efb1873e49463c0929b0a84564ba797d85bb63e759364ae7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 23, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page