A dlt source for the UniRate API — load live currency exchange rates, the supported-currency list, and per-country VAT rates into any dlt destination (DuckDB, BigQuery, Snowflake, Postgres, filesystem, …).
UniRate provides 593+ fiat, crypto, and commodity exchange rates. Latest rates, currencies, and VAT rates are available on the free tier; historical rates require a Pro plan.
dlt has no built-in FX source, so people hand-roll a requests loop or a
rest_api config every time they need exchange rates in a warehouse. This
package gives you a typed, tested @dlt.source with three resources you can
drop straight into a pipeline.
pip install dlt-unirateThis pulls in dlt and requests. Add a destination extra for your target,
e.g. pip install "dlt[duckdb]".
import dlt
from dlt_unirate import unirate_source
pipeline = dlt.pipeline(
pipeline_name="unirate",
destination="duckdb",
dataset_name="unirate_data",
)
# api_key resolves from dlt secrets / the UNIRATE_API_KEY env var,
# or pass it explicitly: unirate_source(api_key="...").
load_info = pipeline.run(unirate_source(base_currency="USD"))
print(load_info)That loads three tables: exchange_rates, currencies, and vat_rates.
unirate_source follows dlt's config/secrets convention. Any of these work:
-
Env var:
export UNIRATE_API_KEY="..." -
dlt secrets —
.dlt/secrets.toml:[sources.unirate] api_key = "..."
-
Explicit argument:
unirate_source(api_key="...")
Get a free key at unirateapi.com.
| Resource | Table columns | Notes |
|---|---|---|
exchange_rates |
base_currency, target_currency, rate |
Every current rate for base_currency. write_disposition="replace". |
currencies |
currency_code |
All supported currency codes. replace. |
vat_rates |
country_code, country_name, vat_rate |
Per-country VAT rates. replace. |
historical_exchange_rates |
date, base_currency, target_currency, rate |
Pro-gated — off by default. merge on (date, base, target). |
| Parameter | Default | Description |
|---|---|---|
api_key |
dlt secret / UNIRATE_API_KEY |
UniRate API key. |
base_currency |
"USD" |
Base for exchange_rates (and historical). |
base_url |
https://api.unirateapi.com |
API base URL. |
request_timeout |
30 |
Per-request timeout, seconds. |
include_historical |
False |
Also yield the Pro-gated historical resource. |
historical_dates |
None |
YYYY-MM-DD dates to pull historical rates for. |
source = unirate_source(
base_currency="EUR",
include_historical=True,
historical_dates=["2024-01-01", "2024-02-01"],
)
pipeline.run(source)Historical endpoints return HTTP 403 on the free tier (surfaced as
ProSubscriptionError); a UniRate Pro plan is required.
# Only load exchange rates and currencies.
pipeline.run(unirate_source().with_resources("exchange_rates", "currencies"))Errors raised by the underlying client all inherit from UniRateError:
| HTTP | Exception |
|---|---|
| 401 | AuthenticationError |
| 403 | ProSubscriptionError |
| 404 | InvalidCurrencyError |
| 429 | RateLimitError |
| other non-2xx | APIError (carries status_code) |
| network / transport | UniRateError |
If you want to call the API directly, there are official clients in Python, Node.js, Go, Rust, Java, Ruby, PHP, .NET, and Swift, plus data-stack integrations for dbt, Airflow, and LangChain.
MIT — see LICENSE.