# Python and the CurrencyCore API

> Use the official Python SDK for typed convert and rates calls, with environment-based auth, error handling, and a note on async services.

Canonical: https://currency-core.com/docs/guides/python/
Updated: 2026-11-11
Published: 2026-11-11

---
The official `currencycore` package is generated from the OpenAPI contract and returns typed models. It resolves `CURRENCYCORE_API_KEY`, sets the base URL, and turns non-2xx responses into `ApiException`. For a script, a job, or a synchronous service, it removes most of the boilerplate.

The SDK is synchronous. An async FastAPI or asyncio service should use `httpx` or run the SDK in a worker thread, so it does not block the event loop. [FastAPI with httpx](/docs/guides/fastapi/) shows that path.

The example needs Python 3.9 or later. Free includes 1,000 requests per month at 60 per minute. Live keys require a paid plan; test keys use the same reference data and quota, capped at 60 per minute.

```bash
pip install currencycore
```

```python
from currencycore.client import create_client
from currencycore.exceptions import ApiException

api = create_client()  # reads CURRENCYCORE_API_KEY

try:
    conversion = api.convert(var_from="USD", to="INR", amount=100)
    rates = api.rates_by_base(base="EUR")
    print(conversion.results[0].result, rates.rates["USD"])
except ApiException as error:
    # status and reason come from the HTTP response; read the body for error.code
    print(error.status, error.reason, error.body)
```

`from` is spelled `var_from` because it is a reserved word in Python. `/v1/convert` returns one entry per target, while `/v1/rates/{base}` returns a map with the base at `1`:

```json
{
  "from": "USD",
  "amount": 100,
  "date": "2026-11-10",
  "results": [{ "to": "INR", "result": 8345.0, "rate": 83.45 }]
}
```

```json
{
  "base": "EUR",
  "date": "2026-11-10",
  "rates": { "EUR": 1, "USD": 1.0861, "INR": 91.62 }
}
```

Branch on the status and the `error.code` in the body. `400` means bad input, `401` a bad key, `403` a plan gate or the Free 30-day window, and `429` a rate limit. Honor `Retry-After` on a time-based `429`.

Cache by `date`, base, and the request parameters. Historical dates are stable for normal caching. For today's snapshot, set a TTL from your business tolerance rather than assuming an intraday feed.

## Next steps

- [Official SDKs](/docs/sdks/) for TypeScript, Dart, Kotlin and Swift
- [FastAPI guide](/docs/guides/fastapi/) for an async service
- [API reference](/docs/api/) and [error codes](/docs/errors/)
- [All developer guides](/docs/guides/)
