mostlyright.weather.earnings.capture.base
mostlyright.weather.earnings.capture.base
Section titled “mostlyright.weather.earnings.capture.base”Capture-adapter ABC + the transient audio artifact (Phase 27, 27-03).
The provider-aware webcast capture contract. Each adapter
``detect“s the webcast URLs it handles and
``capture“s an earnings event into an
AudioArtifact — a TRANSIENT temp file that is DELETED after
transcription (D-27.9 legal guardrail: captured audio is never stored-and-served,
only text / derived facts survive).
The ABC is structured so the live-during-call seam slots in cleanly: 27-09
(Wave 5) adds a live() override for the Amazon-IVS live path
(playback.live-video.net → audio_only rendition). This plan is the
VOD/replay path only (the static MP4 exists only AFTER the call), so live()
is intentionally NOT on the ABC yet — the shape (detect + capture +
AudioArtifact) is the seam it will extend.
Classes
Section titled “Classes”AudioArtifact(audio_path, ticker, call_id, …) | A captured-audio handle whose backing file is TRANSIENT (D-27.9). |
|---|---|
CaptureAdapter() | Provider-aware webcast capture contract. |
Exceptions
Section titled “Exceptions”LiveCaptureUnsupported([message, …]) | A capture adapter has NO live-during-call edge (27-09 W5). |
|---|
class mostlyright.weather.earnings.capture.base.AudioArtifact(audio_path, ticker, call_id, source_media_url, is_transient=True)
Section titled “class mostlyright.weather.earnings.capture.base.AudioArtifact(audio_path, ticker, call_id, source_media_url, is_transient=True)”Bases: object
A captured-audio handle whose backing file is TRANSIENT (D-27.9).
audio_path points at a temp file extracted from the captured webcast
media. is_transient is True by design — the file MUST be deleted
after transcription (never persisted or served). cleanup() unlinks it;
the artifact is also a context manager, so with adapter.capture(...) as a
guarantees the audio is gone on exit even if transcription raises.
source_media_url / call_id / ticker carry the capture lineage for
audit (which asset produced these bytes) without retaining the bytes.
audio_path : str
Section titled “audio_path : str”call_id : str
Section titled “call_id : str”cleanup()
Section titled “cleanup()”Delete the transient audio file (idempotent — safe to call twice).
FileNotFoundError (the idempotent double-call, or an already-cleaned
artifact) is suppressed SILENTLY. Any OTHER OSError (e.g.
PermissionError on a read-only mount) is suppressed but LOGGED at
error level: it must NOT propagate out of __exit__ (that would MASK
the original exception the with block was raising — the transcription
error the caller must see), but it means copyrighted earnings audio has
SURVIVED on disk (a D-27.9 violation), so it cannot pass silently — the
log line names the path an operator must reap manually.
- Return type:
None
is_transient : bool
Section titled “is_transient : bool”source_media_url : str
Section titled “source_media_url : str”ticker : str
Section titled “ticker : str”class mostlyright.weather.earnings.capture.base.CaptureAdapter
Section titled “class mostlyright.weather.earnings.capture.base.CaptureAdapter”Bases: ABC
Provider-aware webcast capture contract.
Concrete adapters (Q4CaptureAdapter, later Notified / GlobalMeet /
ChorusCall / self-hosted) implement detect() (does this adapter handle
the URL?) and capture() (event → transient AudioArtifact). A
live() override is added to the fleet in 27-09 for the live-during-call
IVS path; this VOD/replay contract is the seam it extends.
abstractmethod capture(event, **kwargs)
Section titled “abstractmethod capture(event, **kwargs)”Capture event to a transient AudioArtifact.
MUST stay on the public path (no auth/DRM/captcha circumvention — D-27.9)
and MUST return an artifact whose backing file is transient. Raise
CaptureNotAvailable when the
provider template exposes no cold-fetchable HTTP media (e.g. a dial-in
bridge) rather than emitting empty audio.
- Return type:
AudioArtifact - Parameters:
abstractmethod detect(url)
Section titled “abstractmethod detect(url)”Return True iff this adapter handles url’s webcast provider.
live(manifest_url, session=None)
Section titled “live(manifest_url, session=None)”Follow the provider’s LIVE edge, yielding (pcm_frame, spoken_at) (27-09 W5).
The live-during-call seam. Concrete adapters with a fetchable live HLS
edge (Q4LiveCapture = Amazon IVS playback.live-video.net,
ChorusCallLiveCapture) OVERRIDE this to open a
LiveHlsCapturer
against manifest_url and stream PCM frames into the streaming STT
(27-10). Audio is a TRANSIENT frame stream — the generator yields decoded
PCM into the consumer; it NEVER writes audio to disk or serves it (D-27.9).
The ABC DEFAULT raises LiveCaptureUnsupported: a provider with no
live edge (dial-in bridge, SABR/YouTube, Lumi/VOD-only) has no live path,
and the runner routes it to the authoritative post-call batch ledger
instead (D-27.12). session carries any header-gated context (Origin/
Referer/UA/token) a provider needs; Q4/IVS needs none.
exception mostlyright.weather.earnings.capture.base.LiveCaptureUnsupported(message=”, , error_code=None, source=None, request_id=None)
Section titled “exception mostlyright.weather.earnings.capture.base.LiveCaptureUnsupported(message=”, , error_code=None, source=None, request_id=None)”Bases: EarningsError
A capture adapter has NO live-during-call edge (27-09 W5).
ENGINE-LOCAL exception: it subclasses the core EarningsError so
callers filter it with the rest of the earnings-pipeline errors, but it is
deliberately NOT added to packages/core — the live seam is engine-only and
must never touch the parity surface (research() / merge/* /
live/_sources.py). Raised by CaptureAdapter.live() (the ABC default)
for providers whose template has no fetchable live HLS edge — a dial-in bridge
(telephone), a SABR/YouTube stream we have not proven, or a Lumi/VOD-only
provider. The runner routes such a provider to the post-call batch path only
(D-27.12), never opening a live session.
- Parameters:
- Return type: None
default_error_code : str = ‘EARNINGS_LIVE_CAPTURE_UNSUPPORTED’
Section titled “default_error_code : str = ‘EARNINGS_LIVE_CAPTURE_UNSUPPORTED’”Subclass override — the stable string enum surfaced via error_code.