Inquirer
First-wins USD price aggregation over an ordered oracle sequence.
__init__
__init__(self, oracles: Sequence[PriceOracle]) -> None
Hold oracles; query order is construction order.
Parameters
oraclesrequired, Sequence[PriceOracle]none
usd_prices
usd_prices(self, caip19s: Sequence[str]) -> dict[str, Money]
Merged first-wins USD prices for caip19s.
Validates every id up front (CaipParseError before any oracle
call), deduplicates preserving first occurrence, then walks the
oracles in order asking each only for the still-unpriced ids and
stopping early once everything is priced. Unpriced ids are absent
from the result, never an error.
Parameters
caip19srequired, Sequence[str]none
Raises
usd_prices_at
usd_prices_at(self, caip19s: Sequence[str], at_ms: int) -> dict[str, Money]
Merged first-wins USD prices for caip19s as of at_ms.
The same walk as usd_prices: every id is parsed up front
(CaipParseError before any oracle call), the input is
deduplicated preserving first occurrence, oracles are queried in
construction order, each subsequent one is asked only for the
still-unpriced ids, the walk stops once everything is priced, and
unpriced ids are absent from the result.
Two rules apply here and not there. An oracle with no callable
usd_prices_at is SKIPPED and never called, so a 0.1.x oracle
cannot answer a 2021 question with today's number. An oracle whose
unreachable_instant(at_ms) returns a string is SKIPPED WITHOUT
being called, so an instant it cannot reach costs zero I/O.
absences_at reports both kinds of skip.
Raises ValidationError when at_ms is not an integer
(bool included) and CaipParseError for a malformed id.
Parameters
caip19srequired, Sequence[str]none
at_msrequired, intnone
Raises
absences_at
absences_at(self, at_ms: int) -> tuple[str, ...]
One stated reason per oracle that cannot answer at at_ms.
PURE: no I/O, and neither usd_prices nor usd_prices_at is
called on any oracle. The strings come back in construction order,
and an oracle that can answer contributes nothing.
An oracle with a callable unreachable_instant contributes
whatever string it returns for at_ms. Otherwise an oracle with
no callable usd_prices_at contributes the generated sentence
f"{type(oracle).__name__} has no usd_prices_at; it answers the current instant only". An oracle the walk WOULD ask contributes
its own absences when it is a chain in its own right
(_composed_absences), and nothing when it is a leaf.
Raises ValidationError when at_ms is not an integer.
Parameters
at_msrequired, intnone