SDK lifecycle#

Every ABR SDK object wraps a native handle. Releasing that handle correctly is the caller’s responsibility. This page explains how object lifetimes work, why the with block is the recommended pattern, and what happens to child resources when a parent is closed.

Application and its subclasses#

Application is the base class for all ABR runtime objects. When you use ASR, you create an Asr instance; when you use TTS, you create a Tts instance. Both inherit from Application.

You rarely interact with Application directly. Its lifecycle methods (close() and create_event_set()) are inherited by Asr and Tts and behave the same way on any instance.

The context manager pattern#

The recommended way to use any ABR object is inside a with block:

from abr_sdk.asr import Asr

with Asr("/path/to/libniagara_38m_live.so") as asr:
    # use asr here
    ...
# close() is called here, whether the block exits normally or raises

When the with block exits, Python calls __exit__(), which calls close(). This happens on both normal exit and on exceptions. The with block is the safest pattern because cleanup is guaranteed even if your code raises partway through. The same applies to Tts; use a with block and close() is called automatically on exit.

What close() does#

close() releases the native handle and all child resources. The sequence is the same for Asr and Tts:

  1. Any in-progress session is closed.

  2. All EventSet objects owned by the application are closed, which closes their associated Event objects.

  3. The native application handle is freed.

After close() returns, calling any method on the object raises RuntimeError. Calling close() a second time has no effect.

Explicit close()#

When a context manager is not practical, for example when an Asr or Tts instance is owned by a longer-lived class, call close() explicitly:

from abr_sdk.asr import Asr

class Transcriber:
    def __init__(self, library_path: str) -> None:
        self._asr = Asr(library_path)

    def transcribe(self, audio: bytes) -> str:
        return self._asr.process(audio).text

    def shutdown(self) -> None:
        self._asr.close()

Call close() before the object goes out of scope. If close() is never called, the native handle will not be freed until the process exits. The same pattern applies to Tts.

Next steps