Skip to content

mostlyright.finance.transcripts.adapter

Earnings catalog adapter.

The SDK-side consumer of the earnings-audio feed. EarningsAdapter declares SUPPORTED_SOURCES at class level and from_rows projects parser-output rows to a canonical schema with overlay columns. It is reached directly via its class API (from_rows / stream), never through research() or the observation merge join.

Two delivery channels, one source identity. Both earnings.live (faster-whisper small on-device, keyless/offline BYO-audio) and earnings.hosted (fetch from MOSTLYRIGHT_FINANCE_HOSTED_URL) produce byte-identical rows from the same public call audio. The per-row source overlay column is therefore always the shared identity "earnings_call", so a live row and a hosted row reconcile rather than raising SourceMismatchError, while the delivery column carries the channel lineage (live / hosted). The satellite noaa_goes adapter uses the same arrangement.

knowledge_time = transcript availability (post-call), not event_time. The overlay knowledge_time is derived from each row’s transcript_available_at (when the transcript was published), never the call air time. That is the point-in-time invariant that keeps earnings facts safe in research. The point-in-time alignment and leakage assertions themselves live in mostlyright.finance.transcripts.pit.

This adapter is a parser only: it takes already-extracted producer-payload or local-file rows and does not run faster-whisper itself. The live fetch path lazy-imports the STT engine guarded by the [earnings] extra and raises an install hint if it is missing.

AttributeDescription
MOSTLYRIGHT_FINANCE_HOSTED_URLEnv-var name the consumer reads to reach the hosted earnings feed.
EARNINGS_LIVE_STREAM_SOURCEThe live delivery-channel source id.
EARNINGS_SOURCE_IDENTITYThe single shared source identity.
ClassDescription
EarningsAdapter()Thin earnings-feed adapter (live + hosted).

mostlyright.finance.transcripts.adapter.EARNINGS_LIVE_STREAM_SOURCE

Section titled “mostlyright.finance.transcripts.adapter.EARNINGS_LIVE_STREAM_SOURCE”

The live delivery-channel source id. Distinct from the post-call earnings.hosted ledger: rows tagged this way are provisional and excluded from every research and settlement read (see mostlyright.finance.transcripts.pit). It is a per-row overlay value, not a registered adapter source — the live consumer is reached via EarningsAdapter.stream(), never research() / the merge join.

mostlyright.finance.transcripts.adapter.EARNINGS_SOURCE_IDENTITY

Section titled “mostlyright.finance.transcripts.adapter.EARNINGS_SOURCE_IDENTITY”

The single shared source identity. Live STT and the hosted feed transcribe the same upstream public call audio, so both stamp this value and their rows reconcile instead of mismatching.

class mostlyright.finance.transcripts.adapter.EarningsAdapter

Section titled “class mostlyright.finance.transcripts.adapter.EarningsAdapter”

Bases: object

Thin earnings-feed adapter (live + hosted).

fetch(source, ticker, event_date, , client=None, retrieved_at=None)

Section titled “fetch(source, ticker, event_date, , client=None, retrieved_at=None)”

Fetch earnings rows from source.

earnings.hosted (the default path) httpx-fetches the served /facts feed at MOSTLYRIGHT_FINANCE_HOSTED_URL, validates the payload shape, then projects through from_rows(), producing rows byte-identical to the on-device earnings.live tier: the same engine deployed centrally, so only the delivery overlay differs and the shared source identity earnings_call lets live and hosted rows reconcile.

earnings.live runs the on-device faster-whisper small STT path (lazy-imported, guarded by the [earnings] extra). The capture and STT run in the producer engine; the SDK live path here is the keyless/offline BYO-audio entry point, reached via from_rows().

client injects an httpx.Client (tests pass a MockTransport); retrieved_at overrides the overlay retrieval stamp (defaults to now). Raises EarningsError when MOSTLYRIGHT_FINANCE_HOSTED_URL is unset (the hosted path is opt-in) or the fetch fails, and SchemaValidationError when the served payload is malformed (rejected before overlay-stamping).

  • Return type: DataFrame
  • Parameters:
    • source (str)
    • ticker (str)
    • event_date (str)
    • client (httpx.Client | None)
    • retrieved_at (datetime | None)

static from_rows(rows, , source=‘earnings.hosted’, retrieved_at=None)

Section titled “static from_rows(rows, , source=‘earnings.hosted’, retrieved_at=None)”

Project producer-payload / local-file rows to a canonical DataFrame.

Emits the canonical schema.finance.transcript.v1 / schema.finance.fact.v1 fields present on the input rows plus the overlay columns source / retrieved_at / knowledge_time / event_time and the delivery lineage column.

Rows are byte-identical across earnings.live and earnings.hosted; only delivery differs. source is always the shared identity "earnings_call", so live and hosted rows reconcile.

async stream(ticker, call_id, , base_url, token=None, headers=None, client=None)

Section titled “async stream(ticker, call_id, , base_url, token=None, headers=None, client=None)”

Consume the live SSE feed → incremental canonical rows. Async.

Mirrors the CWOP stream() async-generator precedent (mostlyright.weather.cwop.stream()): an async for over this yields incremental schema.finance.transcript.v1 / schema.finance.fact.v1 rows as the call airs. Every row is tagged source="earnings.hosted.stream" (EARNINGS_LIVE_STREAM_SOURCE) and carries:

  • spoken_at — the aired event time (from the payload’s spoken_at / event_time);
  • knowledge_time — the STT-finalization / publish wallclock (>= spoken_at, from the payload’s published_at / knowledge_time; never spoken_at);
  • stream_seq — the SSE id: (monotonic; drives resume);
  • is_final — STT-segment finality only, never settlement authority;
  • resolution_status"provisional" for a counted fact delta.

The consumer is a pure pass-through for kalshi_counted: it reads it straight from the fact-delta row and never re-derives counts client-side, so the fail-closed rule stays with the producer. A resume_incomplete frame is returned as a row with event="resume_incomplete" so a caller reconciles from the ledger rather than silently gapping.

  • Parameters:
    • ticker (str) – The issuer ticker (a query param on the /stream URL).
    • call_id (str) – The call id (a query param on the /stream URL).
    • base_url (str) – The /stream endpoint served by the producer. The SDK ships no default.
    • token (str | None) – A short-lived signed-URL token (the browser EventSource path cannot set a header; the server-side httpx reader here can, but the token is passed as a query param for wire parity).
    • headers (Mapping[str, str] | None) – Extra request headers (e.g. an Authorization header for the header-auth reader variant).
    • client (object | None) – An optional httpx.AsyncClient (tests inject a mock transport). Passed straight to consume_sse().
  • Yields: Canonical row dicts tagged source="earnings.hosted.stream".
  • Return type: AsyncIterator[dict[str, object]]

mostlyright.finance.transcripts.adapter.MOSTLYRIGHT_FINANCE_HOSTED_URL

Section titled “mostlyright.finance.transcripts.adapter.MOSTLYRIGHT_FINANCE_HOSTED_URL”

Env-var name the consumer reads to reach the hosted earnings feed.