Skip to main content

Zero-dependency command-line client for the Frankfurter foreign-exchange API

Project description

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

Project details


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.

Supported by

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