angee.integrate.session
Worker-only live bridge session loop.
This module owns the long-lived task discipline shared by live bridges: QR reporting, bounded wake checks, cooperative stop, advisory-lock liveness, and the proof that a vendor connection released its store before deletion. It imports qrcode at module top by design, so console-safe paths import integrate.live instead.
PasswordSkipped
class PasswordSkipped()Type of the explicit optional-password skip sentinel.
PASSWORD_SKIPPED
An optional password round was skipped; distinct from the abort value None.
LiveSession
class LiveSession()One live vendor connection: pairing, event drain, and cooperative stop.
__init__
def __init__(bridge: Any, *, reporter: BridgeProgressReporter,
stop_event: threading.Event) -> NoneBind the session to one bridge row and its progress reporter.
run
def run() -> PairingStateConnect and drain events until stopped, logged out, disconnected, or unlocked.
discard_store
def discard_store() -> NoneDelete this session's store only after the vendor connection released it.
discard_new_store
def discard_new_store() -> NoneDiscard the store only when this session created its pairing material.
A duplicate rejection means another bridge owns this account. That is not proof this row's retained session credential is void: a disconnected bridge may retain its account identity and store, release the claim, and later resume after another bridge has claimed the same account. Deleting here would destroy the credential disconnect was designed to preserve. A session that found no store file is the only one that created what it would delete; the rest report the conflict and leave the store for an explicit pairing reset.
The store answers that question (:attr:created_store), not the row's account claim: this path's own release_account drops the claim before the discard runs, so deriving it from the row would read "no prior claim" on the operator's second identical attempt and wipe the credential the first one correctly kept.
request_password
def request_password(message: str = "",
*,
material_key: str = "password",
optional: bool = False) -> str | PasswordSkipped | NoneAsk for one transient secret, a skip sentinel, or None on stop.
message is a non-secret, operator-visible prompt from the vendor. material_key selects the consume-once credential key. Optional rounds may be explicitly skipped without conflating that choice with shutdown. Vendor connections call this from their own thread. The queue wait stays bounded by the short awaiting-password wake so a task-thread stop decision can unwind a vendor blocked here without outliving cooperative shutdown.