cadrumo.adapters.outbound.fx.ecb_provider module

ECB euro reference-rate exchange-rate provider.

Implements the domain.currency.service.ExchangeRateProvider protocol against the European Central Bank Data Portal, resolving each rate from the published series at lookup time. The ECB rates are the official exchange rate of Spanish law (Ley 46/1998 art. 36) accepted for IRPF, IVA, and PGC conversion.

The ECB publishes EUR-base quotes (1 EUR = rate CCY). The domain.currency.service.CurrencyNormalizationService expects get_eur_rate to return CCY->EUR (so eur = amount * rate), so this provider returns 1 / ecb_rate.

The ECB publishes only on TARGET working days and the Data Portal answers a non-publication date with an empty result set, so a lookup widens its query window backwards by LOOKBACK_DAYS and takes the most recent published observation on or before the requested date.

A transport or protocol failure raises domain.currency.errors.ExchangeRateProviderError rather than returning None: an unreachable ECB must not be indistinguishable from a currency the ECB does not publish, which would silently degrade ledger rows to a zero EUR value.

The default transport (_https_fetch()) reaches the live European Central Bank host unconditionally, because reaching it is what this adapter is for. Holding a deterministic suite off that host is a TEST concern, carried by the aeat_live marker rather than by a production branch: a deterministic suite injects a RateFetch transport (tests.ecb_stub.ecb_csv_fetch), and a test that genuinely wants the published series declares aeat_live and is selected only by the live lane.

RateFetch

given a URL, return the response body as text.

Type:

Transport contract

alias of Callable[[str], str]

ECB_RATE_SOURCE_ID

Identifier stamped on every record this provider converts. Names the ECB euro reference-rate series specifically, not merely “an exchange-rate provider”, because the stamp’s job is to let a later reader re-fetch the same published observation and re-derive the stored euro figure (Ley 46/1998 art. 36).

class EcbReferenceRateProvider(*, fetch=None, lookback_days=14)[source]

Bases: object

EUR reference-rate provider backed by the live ECB Data Portal series.

Parameters:
property rate_source_id: str

Return ECB_RATE_SOURCE_ID, the stamped rate authority.

get_eur_rate(currency, rate_date)[source]

Return the CCY->EUR rate for rate_date (or most-recent prior).

Returns None when the ECB publishes no series for currency, or no observation within the lookback window ending at rate_date.

Raises:

ExchangeRateProviderError – When the ECB Data Portal cannot be reached or returns an unusable response.

Return type:

Decimal | None

Parameters:
default_ecb_rate_provider()[source]

Return the process-wide EcbReferenceRateProvider (cached).

Caching the instance keeps its per-(currency, date) memo shared across every lookup in the process, so a multi-row ledger import re-uses resolved rates. Process hosts bind this as their exchange-rate provider factory; conversion code resolves the bound provider rather than calling this directly.

Return type:

EcbReferenceRateProvider