Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Context

prism.Context

A Prism context.

Syntax

class Context(
    registry: Registry | None = None,
    *,
    on_availability: AvailabilityCallback | None = None,
    on_baseline: BaselineCallback | None = None,
    poll_interval_ms: int = 0,
    debounce_samples: int = 0,
    backoff_max_ms: int = 0,
    auto_power_manage: bool = True,
)

Parameters

registry

The registry to use, or None for the global registry. The context keeps its own reference, so registry MAY be closed afterwards.

on_availability

A function called with a BackendId, the backend’s name, and True if the backend became available or False if it became unavailable; or None to disable availability monitoring. It MAY be a coroutine function. The remaining arguments are ignored when it is None.

on_baseline

A function called with no arguments when the baseline is set, or None. It MAY be a coroutine function.

poll_interval_ms

The base interval between samples, in milliseconds. 0 selects 1000.

debounce_samples

The number of consecutive samples that MUST agree before a change is reported. 0 selects 2; 1 reports changes immediately.

backoff_max_ms

The longest interval between samples, in milliseconds. 0, or a value not greater than poll_interval_ms, keeps the interval constant.

auto_power_manage

Whether to stop sampling while the system is suspended. It has an effect only where auto_power_supported returns True.

Exceptions

RuntimeError

If the context cannot be created.

Remarks

This class wraps prism_init and prism_shutdown. A context is bound to a registry when it is created: the global registry, which contains the backends compiled into Prism, or a prism.Registry, which MAY also contain custom backends and backends from shared libraries. Backends are ordered by priority, highest first; screen readers have higher priority than speech engines.

create and create_best return independent instances. acquire, acquire_best, and get return a shared instance, as described under Backend.

The methods of a context MAY be called from any thread. The context is shut down when the object is destroyed. Backends obtained from it remain usable.

Availability monitoring

A context created with on_availability samples the availability of every backend on a background thread, and calls on_availability when a backend becomes available or unavailable. A context created without it starts no thread.

The first sample of each backend sets a baseline and is not reported. A change is reported once it has been observed on debounce_samples consecutive samples. If backoff_max_ms is greater than poll_interval_ms, the interval between samples doubles while nothing changes, up to backoff_max_ms, and returns to poll_interval_ms when a change is observed.

The baseline is set after the constructor returns. A change that occurs between the application’s own check of a backend and the baseline sample of that backend is part of the baseline and is not reported. on_baseline is called once the baseline is set, before any call to on_availability. An application that checks availability before then, and keeps the result, SHOULD check again when on_baseline is called. A later notification MAY report a change it has already seen.

Callbacks are not called on Prism’s sampling thread. Each notification is passed to a thread of the binding that runs an asyncio event loop, so a callback MAY block. A callback MAY be a coroutine function, in which case its coroutine runs on that loop. At most one coroutine runs at a time for each backend; a newer notification for the backend replaces one that is waiting to run. Exceptions from callbacks are logged to the prism.dispatch logger. Coroutines still running when the context is destroyed are cancelled. Callbacks MUST synchronize access to shared state, including backends used on other threads.

Context.backends_count

The number of backends in the registry.

Syntax

backends_count: int  # read-only

Remarks

Wraps prism_registry_count. The value includes backends that cannot be used on the current system, and does not change for the life of the registry. 0 means Prism was built without backends for the platform.

Context.id_of

Returns the identifier of a backend, given its position or its name.

Syntax

def id_of(index_or_name: int | str) -> BackendId

Parameters

index_or_name

The position of the backend in the registry, or its name.

Return Value

The identifier of the backend.

Exceptions

KeyError

If no backend is at the position or has the name.

TypeError

If index_or_name is neither an int nor a str. A bool is not accepted.

Remarks

This method wraps prism_registry_id_at and prism_registry_id. Positions run from 0, the highest-priority backend, to one less than backends_count. Names are compared exactly, including case.

Context.name_of

Returns the name of a backend.

Syntax

def name_of(backend_id: BackendId) -> str

Parameters

backend_id

The identifier of the backend.

Return Value

The name of the backend.

Exceptions

KeyError

If the registry does not contain the backend.

Remarks

This method wraps prism_registry_name.

Context.priority_of

Returns the priority of a backend.

Syntax

def priority_of(backend_id: BackendId) -> int

Parameters

backend_id

The identifier of the backend.

Return Value

The priority, or -1 if the registry does not contain the backend.

Remarks

This method wraps prism_registry_priority. Priorities are non-negative; higher priorities are tried first by create_best and acquire_best. The priorities of built-in backends MAY change between releases.

Context.exists

Reports whether the registry contains a backend.

Syntax

def exists(backend_id: BackendId) -> bool

Parameters

backend_id

The identifier of the backend.

Return Value

True if the registry contains the backend.

Remarks

This method wraps prism_registry_exists. It does not report whether the backend can be used; see BackendFeatures.is_supported_at_runtime.

Context.get

Returns the shared instance of a backend, if one exists.

Syntax

def get(backend_id: BackendId) -> Backend | None

Parameters

backend_id

The identifier of the backend.

Return Value

The shared instance, or None.

Exceptions

PrismError

If the instance exists but cannot be initialized.

Remarks

This method wraps prism_registry_get. It never creates an instance. It returns the instance obtained through acquire or acquire_best while any object referring to that instance remains.

Context.create

Creates and initializes an instance of a backend.

Syntax

def create(backend_id: BackendId) -> Backend

Parameters

backend_id

The identifier of the backend.

Return Value

The backend.

Exceptions

ValueError

If the registry does not contain the backend, or the backend cannot be created.

PrismBackendNotAvailableError

If a component the backend requires is missing or not running.

PrismError

If initialization fails for another reason.

Remarks

This method wraps prism_registry_create and prism_backend_initialize. Each call creates an independent instance. Initialization MAY take noticeable time.

Context.create_best

Creates and initializes the highest-priority backend that can be initialized.

Syntax

def create_best() -> Backend

Return Value

The backend.

Exceptions

ValueError

If no backend can be initialized, as on a system with no speech engine. Applications MUST handle this case.

Remarks

This method wraps prism_registry_create_best. Backends are tried in priority order, and the first that initializes is returned. A screen reader backend initializes only while its screen reader is running, so the result is the user’s screen reader if one is running, and otherwise a speech engine.

The choice is not revisited: a backend obtained while no screen reader was running remains a speech engine if one is started later. Availability monitoring, described under Context, reports such changes.

Context.acquire

Returns the shared instance of a backend, creating it if necessary.

Syntax

def acquire(backend_id: BackendId) -> Backend

Parameters

backend_id

The identifier of the backend.

Return Value

The backend.

Exceptions

ValueError

If the registry does not contain the backend, or the backend cannot be created.

PrismBackendNotAvailableError

If a component the backend requires is missing or not running.

PrismError

If initialization fails for another reason.

Remarks

This method wraps prism_registry_acquire and prism_backend_initialize. The instance is shared as described under Backend. create SHOULD be used unless the instance is meant to be shared.

Context.acquire_best

Returns the shared instance of the highest-priority backend that can be initialized.

Syntax

def acquire_best() -> Backend

Return Value

The backend.

Exceptions

ValueError

If no backend can be initialized.

Remarks

This method wraps prism_registry_acquire_best. Backends are tried in priority order, as for create_best, using existing shared instances where they exist. create_best SHOULD be used unless the instance is meant to be shared.

Context.pause_availability_polling

Pauses availability monitoring.

Syntax

def pause_availability_polling() -> None

Remarks

This method wraps prism_availability_poll_pause. While paused, the sampling thread uses no processor time. A sample in progress completes. The method does nothing if monitoring is disabled or already paused.

Context.resume_availability_polling

Resumes availability monitoring.

Syntax

def resume_availability_polling() -> None

Remarks

This method wraps prism_availability_poll_resume. Every backend is sampled immediately, and each whose availability differs from what was last reported is reported without debouncing. A change that occurred and reverted while paused is not reported. The method does nothing if monitoring is disabled or not paused.

Context.auto_power_supported

Reports whether auto_power_manage has an effect.

Syntax

@staticmethod
def auto_power_supported() -> bool

Return Value

True if automatic power management is supported.

Remarks

This method wraps prism_availability_auto_power_supported. Where it returns False, sampling continues while the system is suspended unless pause_availability_polling is called. The result depends only on the platform and build, and the method MAY be called at any time.