FastAPI integration for the UniRate currency-exchange API — async dependency, lifespan manager, Money Pydantic type, and response-conversion middleware.
Project description
fastapi-unirate
FastAPI integration for the UniRate currency-exchange API:
- Async dependency —
Depends(get_unirate_client)plus a typedUniRateDepalias for path-operation signatures. - Lifespan helper — one shared
httpx.AsyncClient-backed UniRate client per app, opened on startup and closed on shutdown. MoneyPydantic type — amount + currency pair that round-trips through OpenAPI schemas.CurrencyConversionMiddleware— auto-rewrites Money-shaped values in JSON responses to a request-scoped target currency (?currency=EUR).
UniRate covers 593+ fiat, crypto, and commodity codes. Latest rates and
conversion are on the free tier; historical endpoints
(convert_historical) require Pro.
Install
pip install fastapi-unirate
Or with uv / Poetry:
uv add fastapi-unirate
poetry add fastapi-unirate
Quick start
import os
from fastapi import FastAPI
from fastapi_unirate import (
CurrencyConversionMiddleware,
Money,
UniRateDep,
unirate_lifespan,
)
app = FastAPI(lifespan=unirate_lifespan()) # reads UNIRATE_API_KEY from env
app.add_middleware(CurrencyConversionMiddleware)
@app.get("/products/widget")
async def get_widget() -> dict[str, Money]:
return {"price": Money(amount=19.99, currency="USD")}
@app.get("/rate/{base}/{quote}")
async def rate(base: str, quote: str, client: UniRateDep) -> dict[str, float]:
return {"rate": await client.get_rate(base, quote)}
Then:
$ curl localhost:8000/products/widget
{"price":{"amount":19.99,"currency":"USD"}}
$ curl localhost:8000/products/widget?currency=EUR
{"price":{"amount":18.42,"currency":"EUR"}}
$ curl localhost:8000/rate/USD/JPY
{"rate":151.83}
The middleware finds every {"amount": <number>, "currency": "<code>"}
shape — top-level, nested, or inside lists — and rewrites it. Conversions
are de-duplicated per request and run concurrently.
Configuration
unirate_lifespan accepts overrides:
app = FastAPI(
lifespan=unirate_lifespan(
api_key="...", # default: $UNIRATE_API_KEY
base_url="https://api.unirateapi.com", # default: production
timeout=15.0, # default: 30s
)
)
CurrencyConversionMiddleware accepts the query-parameter name and an
explicit client (mostly for testing):
app.add_middleware(
CurrencyConversionMiddleware,
query_param="display_currency",
)
Why a middleware?
The dossier sketched two integration shapes — DI and middleware — and both pull their weight:
- The DI provider is the right tool when a handler explicitly wants to
call
convert()orget_rate(). - The middleware is the right tool when a service has a stable
Money-shaped response and wants to expose one?currency=knob to clients without rewriting every handler.
You can use either, or both together (as in the quick-start example).
Errors
The client raises UniRateAPIError on non-2xx responses (with
status_code set). Common cases:
| HTTP | Meaning |
|---|---|
| 401 | Missing or invalid API key |
| 403 | Pro subscription required (historical, commodities) |
| 404 | Currency not found |
| 429 | Rate limit exceeded |
The middleware swallows UniRateAPIError and passes the original
response through unchanged — so an upstream UniRate outage never becomes
a 500 on your service.
Compatibility
- Python 3.9 – 3.13
- FastAPI ≥ 0.100
- Pydantic ≥ 2.0
Related
unirate-api— sync UniRate Python client (this package vendors a small async equivalent so it doesn't pull inrequests).langchain-unirate— LangChain partner package.- Other UniRate integrations: dbt, Airflow, n8n, Raycast, MCP server. Full list at https://unirateapi.com.
License
MIT
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 Distribution
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 fastapi_unirate-0.1.0.tar.gz.
File metadata
- Download URL: fastapi_unirate-0.1.0.tar.gz
- Upload date:
- Size: 12.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
55de2a8b8f53f565f8ecad5d83318aa47cc9f89e825f285aa3eab9866e87a183
|
|
| MD5 |
2d6c616ad6919f63894be521714f27ae
|
|
| BLAKE2b-256 |
dfe61200e1fbac4ecafa11a8e0b9e40123dfd65a1e492d22dd181153252cf392
|
Provenance
The following attestation bundles were made for fastapi_unirate-0.1.0.tar.gz:
Publisher:
release.yml on UniRate-API/fastapi-unirate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastapi_unirate-0.1.0.tar.gz -
Subject digest:
55de2a8b8f53f565f8ecad5d83318aa47cc9f89e825f285aa3eab9866e87a183 - Sigstore transparency entry: 1468967484
- Sigstore integration time:
-
Permalink:
UniRate-API/fastapi-unirate@313be3bab4b8d32355e84e64ac97956c9a20639c -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/UniRate-API
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@313be3bab4b8d32355e84e64ac97956c9a20639c -
Trigger Event:
push
-
Statement type:
File details
Details for the file fastapi_unirate-0.1.0-py3-none-any.whl.
File metadata
- Download URL: fastapi_unirate-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
42b7bc355a22c605fcca9a39e515e997cf1233fe7cc632c7df44659260b0ec24
|
|
| MD5 |
7852247a755fd18db57d4ceb43a03c65
|
|
| BLAKE2b-256 |
d0bf480eafd70d81859bff1b2f938ae08ecb95ebd83d7709dc7027b10622e751
|
Provenance
The following attestation bundles were made for fastapi_unirate-0.1.0-py3-none-any.whl:
Publisher:
release.yml on UniRate-API/fastapi-unirate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastapi_unirate-0.1.0-py3-none-any.whl -
Subject digest:
42b7bc355a22c605fcca9a39e515e997cf1233fe7cc632c7df44659260b0ec24 - Sigstore transparency entry: 1468967582
- Sigstore integration time:
-
Permalink:
UniRate-API/fastapi-unirate@313be3bab4b8d32355e84e64ac97956c9a20639c -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/UniRate-API
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@313be3bab4b8d32355e84e64ac97956c9a20639c -
Trigger Event:
push
-
Statement type: