aboutsummaryrefslogtreecommitdiff
path: root/backends/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'backends/__init__.py')
-rw-r--r--backends/__init__.py146
1 files changed, 0 insertions, 146 deletions
diff --git a/backends/__init__.py b/backends/__init__.py
deleted file mode 100644
index 6a23ab7..0000000
--- a/backends/__init__.py
+++ /dev/null
@@ -1,146 +0,0 @@
-"""Registry of the TTS backends the audiobook generator can talk to.
-
-Each backend (audio.cpp, qwen, faster) lives in its own module and owns
-its setup wizard, its status detection, and the launch command it prints
-once configured. This package aggregates them into a single registry so
-``audiobook.py``'s TUI hub and future tools can iterate backends without
-hardcoding their names: ``backends.detect_all()`` reports which are set
-up (and whether their server is currently running), and the registry
-drives the hub's setup/configure menus.
-
-The registry is built lazily on the first call to ``get``/``detect_all``/
-``detect`` (not at package import time), because the backend modules pull
-in ``converter.tts`` and its third-party dependencies, which are only
-available inside the managed venv that ``audiobook.py`` bootstraps before
-importing them. ``backends.envs`` is imported during that bootstrap, so
-importing this package must stay cheap and dependency-free.
-
-Adding a backend: create ``backends/<name>.py`` exposing
-``detect() -> BackendStatus``, ``run_tui() -> int`` and
-``configure_actions: list[ConfigureAction]``, then append a ``BackendInfo`` in
-``_build_registry`` below. ``audiobook.py`` and the hub pick it up
-automatically.
-"""
-
-import shlex
-from dataclasses import dataclass, field
-from typing import Callable, List, Optional
-
-
-@dataclass
-class ServerSpec:
- """One launchable server process for a backend.
-
- A backend may expose more than one server (qwen runs CustomVoice and Base
- on separate ports). ARGV is the exact command line the hub spawns (using
- the managed venv's absolute binaries, so no shell activation is needed);
- URL is the endpoint ``common.server_running`` probes to decide readiness.
- """
- name: str
- url: str
- argv: List[str]
-
-
-@dataclass
-class BackendStatus:
- """How far a backend is set up, plus the command to start it.
-
- INSTALLED means the backend itself is present (a cloned + built
- checkout, or a pip package). CONFIGURED means the supporting files are
- in place (a server.json / voices.json and a converter/config.py that
- points at the right port). RUNNING means an external server is
- currently accepting connections on the configured port (probed by
- ``backends.common.server_running``). DETAILS are short status lines for
- the hub. LAUNCH_HINT is the human-readable command(s) the user runs to
- start the server, derived from SERVERS by ``format_launch_hint``.
- SERVERS is the machine-usable list of server processes the hub can
- start/stop (empty when the backend is not yet configured).
- """
- key: str
- label: str
- installed: bool
- configured: bool
- running: bool = False
- details: List[str] = field(default_factory=list)
- launch_hint: str = ""
- servers: List[ServerSpec] = field(default_factory=list)
-
- @property
- def ready(self) -> bool:
- """True when the backend is installed and configured for use."""
- return self.installed and self.configured
-
-
-def format_launch_hint(servers: List[ServerSpec]) -> str:
- """Join a backend's server argvs into a copy-pasteable launch hint."""
- return " ; ".join(shlex.join(s.argv) for s in servers)
-
-
-@dataclass
-class ConfigureAction:
- """A per-backend "configure" menu entry (e.g. "New server.json")."""
- label: str
- run: Callable[[], int]
-
-
-@dataclass
-class BackendInfo:
- """One registry entry: identity, detector, setup wizard, configure menu."""
- key: str
- label: str
- detect: Callable[[], BackendStatus]
- setup_tui: Callable[[], int]
- configure_actions: List[ConfigureAction] = field(default_factory=list)
-
-
-REGISTRY: List[BackendInfo] = []
-_BY_KEY: dict = {}
-
-
-def _build_registry() -> None:
- """Import the backend modules and wire up REGISTRY (once)."""
- if REGISTRY:
- return
- from . import audiocpp, faster, qwen
-
- REGISTRY.append(BackendInfo(
- key="audiocpp",
- label="audio.cpp",
- detect=audiocpp.detect,
- setup_tui=audiocpp.run_tui,
- configure_actions=audiocpp.configure_actions,
- ))
- REGISTRY.append(BackendInfo(
- key="qwen",
- label="qwen-tts",
- detect=qwen.detect,
- setup_tui=qwen.run_tui,
- configure_actions=qwen.configure_actions,
- ))
- REGISTRY.append(BackendInfo(
- key="faster",
- label="faster-qwen3-tts",
- detect=faster.detect,
- setup_tui=faster.run_tui,
- configure_actions=faster.configure_actions,
- ))
- for info in REGISTRY:
- _BY_KEY[info.key] = info
-
-
-def get(key: str) -> Optional[BackendInfo]:
- """Return the registry entry for KEY, or None."""
- _build_registry()
- return _BY_KEY.get(key)
-
-
-def detect_all() -> List[BackendStatus]:
- """Detect every registered backend's status, in registry order."""
- _build_registry()
- return [info.detect() for info in REGISTRY]
-
-
-def detect(key: str) -> Optional[BackendStatus]:
- """Detect a single backend by key."""
- info = get(key)
- return info.detect() if info is not None else None