Skip to main content

kiarina-currency

PyPI Python License

English | 日本語

Dependencies

Package Version License
HTTPX >=0.28.1 BSD-3-Clause
kiarina-utils-common >=1.11.0 MIT
Pydantic >=2.10.6 MIT
pydantic-settings >=2.7.1 MIT
pydantic-settings-manager >=3.2.0 MIT

Installation

pip install kiarina-currency

Features

  • Detect the system currency Resolve an ISO 4217 currency code from locale settings and environment variables.
  • Get exchange rates Retrieve rates from configured static data or the Frankfurter API.
  • Extend rate providers Select an implementation by provider instance, registered name, or import path.

Detecting the System Currency

from kiarina.currency import get_system_currency

currency = get_system_currency()

Detection checks locale.localeconv(), the locale name, LC_ALL, LC_MONETARY, and LANG. It returns "USD" when detection fails.

Getting Exchange Rates

The static provider is used by default.

from kiarina.currency import get_exchange_rate

rate = await get_exchange_rate("USD", "JPY")

The static provider resolves direct rates, inverted rates, and indirect rates through the base currency, in that order. A fallback value can be provided when a rate is unavailable.

rate = await get_exchange_rate("USD", "XXX", default=1.0)

The Frankfurter provider retrieves rates from the Frankfurter API.

rate = await get_exchange_rate(
    "USD",
    "EUR",
    rate_options={"rate_provider": "frankfurter"},
)

Configuring Providers

Settings are managed by pydantic-settings-manager. For example, static rates can be configured at runtime.

from kiarina.currency import get_exchange_rate
from kiarina.currency.rate_provider_impl.static import settings_manager

settings_manager.cli_args = {
    "base_currency": "USD",
    "rates": {
        "USD": {
            "EUR": 0.85,
            "JPY": 150.0,
        },
    },
}

rate = await get_exchange_rate("JPY", "EUR")

Environment variable names combine each settings class prefix with its field name.

Setting Environment Variable
Default provider KIARINA_CURRENCY_RATE_PROVIDER_DEFAULT
Static provider base currency KIARINA_CURRENCY_RATE_PROVIDER_IMPL_STATIC_BASE_CURRENCY
Frankfurter API base URL KIARINA_CURRENCY_RATE_PROVIDER_IMPL_FRANKFURTER_BASE_URL
Frankfurter API timeout KIARINA_CURRENCY_RATE_PROVIDER_IMPL_FRANKFURTER_TIMEOUT

Creating a Custom Provider

An instance implementing the RateProvider protocol can be passed directly.

from kiarina.currency import CurrencyCode, get_exchange_rate
from kiarina.currency.rate_provider import BaseRateProvider


class CustomRateProvider(BaseRateProvider):
    async def get_rate(
        self,
        from_currency: CurrencyCode,
        to_currency: CurrencyCode,
        *,
        default: float | None = None,
    ) -> float:
        return 1.5


rate = await get_exchange_rate(
    "USD",
    "EUR",
    rate_options={"rate_provider": CustomRateProvider()},
)

A provider can also be created from a registered name or import path.

from kiarina.currency import create_rate_provider

provider = create_rate_provider("my_package.providers:CustomRateProvider")

When an import path omits the class name, :RateProvider is appended.

API Reference

kiarina.currency

from kiarina.currency import (
    CurrencyCode,
    CurrencyError,
    ExchangeRateNotFoundError,
    RateOptions,
    RateProvider,
    RateProviderName,
    RateProviderSettings,
    create_rate_provider,
    get_exchange_rate,
    get_system_currency,
    rate_provider_settings_manager,
)

Functions

def get_system_currency() -> CurrencyCode: ...

async def get_exchange_rate(
    from_currency: CurrencyCode,
    to_currency: CurrencyCode,
    *,
    default: float | None = None,
    rate_options: RateOptions | None = None,
) -> float: ...

def create_rate_provider(
    provider_name: RateProviderName | ImportPath | None = None,
    **kwargs: Any,
) -> RateProvider: ...

get_system_currency returns the system currency and falls back to "USD" when detection fails.

get_exchange_rate retrieves a rate from the selected provider. It raises ExchangeRateNotFoundError when the rate is unavailable and no default is provided.

create_rate_provider creates a provider from a registered name or import path. It raises TypeError when the resulting object does not implement RateProvider.

RateProvider

@runtime_checkable
class RateProvider(Protocol):
    async def get_rate(
        self,
        from_currency: CurrencyCode,
        to_currency: CurrencyCode,
        *,
        default: float | None = None,
    ) -> float: ...

Settings

class RateProviderSettings(BaseSettings):
    default: RateProviderName = "static"
    providers: dict[RateProviderName, ImportPath] = {
        "frankfurter": "kiarina.currency.rate_provider_impl.frankfurter:FrankfurterRateProvider",
        "static": "kiarina.currency.rate_provider_impl.static:StaticRateProvider",
    }

rate_provider_settings_manager: SettingsManager[RateProviderSettings]

rate_provider_settings_manager is an alias for kiarina.currency.rate_provider.settings_manager.

Types

CurrencyCode: TypeAlias = str
RateProviderName: TypeAlias = str

class RateOptions(TypedDict, total=False):
    rate_provider: RateProvider | RateProviderName | ImportPath | None

CurrencyCode represents an ISO 4217 currency code. RateOptions.rate_provider accepts a provider instance, registered name, import path, or None.

Exceptions

class CurrencyError(Exception): ...

class ExchangeRateNotFoundError(CurrencyError): ...

kiarina.currency.rate_provider

from kiarina.currency.rate_provider import (
    BaseRateProvider,
    RateProvider,
    RateProviderName,
    RateProviderSettings,
    create_rate_provider,
    settings_manager,
)

BaseRateProvider

class BaseRateProvider(RateProvider, ABC):
    def __init__(self, **kwargs: Any) -> None: ...

    @abstractmethod
    async def get_rate(
        self,
        from_currency: CurrencyCode,
        to_currency: CurrencyCode,
        *,
        default: float | None = None,
    ) -> float: ...

Use this base class for custom providers and implement get_rate.

settings_manager: SettingsManager[RateProviderSettings]

kiarina.currency.rate_provider_impl.static

from kiarina.currency.rate_provider_impl.static import (
    StaticRateProvider,
    StaticRateProviderSettings,
    settings_manager,
)

StaticRateProvider

class StaticRateProvider(BaseRateProvider):
    async def get_rate(
        self,
        from_currency: CurrencyCode,
        to_currency: CurrencyCode,
        *,
        default: float | None = None,
    ) -> float: ...

Settings

class StaticRateProviderSettings(BaseSettings):
    base_currency: CurrencyCode = "USD"
    rates: dict[CurrencyCode, dict[CurrencyCode, float]]

settings_manager: SettingsManager[StaticRateProviderSettings]

rates is nested by source currency, target currency, and rate.

kiarina.currency.rate_provider_impl.frankfurter

from kiarina.currency.rate_provider_impl.frankfurter import (
    FrankfurterRateProvider,
    FrankfurterRateProviderSettings,
    settings_manager,
)

FrankfurterRateProvider

class FrankfurterRateProvider(BaseRateProvider):
    async def get_rate(
        self,
        from_currency: CurrencyCode,
        to_currency: CurrencyCode,
        *,
        default: float | None = None,
    ) -> float: ...

When an HTTP error, network error, timeout, or missing rate occurs, the provider returns default when supplied. Otherwise, it raises ExchangeRateNotFoundError.

Settings

class FrankfurterRateProviderSettings(BaseSettings):
    base_url: str = "https://api.frankfurter.app"
    timeout: float = 10.0

settings_manager: SettingsManager[FrankfurterRateProviderSettings]

Metadata

Release files for kiarina-currency 2.3.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 kiarina-currency 2.3.1
File Size Uploaded Provenance Actions
kiarina_currency-2.3.1.tar.gz 12.3 kB With provenance Details for kiarina_currency-2.3.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for kiarina-currency 2.3.1
File Interpreter ABI Platform Actions
kiarina_currency-2.3.1-py3-none-any.whl Python 3 none any Details for kiarina_currency-2.3.1-py3-none-any.whl

Total release size: 28.6 kB

Release files / kiarina_currency-2.3.1.tar.gz

Download URL kiarina_currency-2.3.1.tar.gz
Size 12.3 kB
Tags Source
SHA-256 checksum
How to use checksums
39f462407be82ed266c94ee1c3251fbe93160656b0b27b74b07fc095dbbff41b
BLAKE2b-256 checksum
How to use checksums
bb7206a22448c8351f47dc798add0225905562682b1d768685cadb340000781f
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 Jul 2, 2026.

Transparency log

Release files / kiarina_currency-2.3.1-py3-none-any.whl

Download URL kiarina_currency-2.3.1-py3-none-any.whl
Size 16.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cd568a67615125469e467c59bd1ed6f662b387cfe0b27391c3e73b571da55e49
BLAKE2b-256 checksum
How to use checksums
7d8c59197c3184d46b7dffaf44ca769db1b59b2f9ba30ae6ca4664d82ba65689
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 Jul 2, 2026.

Transparency log

Security for kiarina-currency 2.3.1

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for kiarina_currency-2.3.1.tar.gz

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 Jul 2, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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