From 5c50cd49d5906000cd8208cda5f99b1038387bdb Mon Sep 17 00:00:00 2001 From: Beckett Frey Date: Thu, 21 May 2026 08:01:35 -0700 Subject: [PATCH 01/10] Move possible audio extensions to shared constants --- src/voxkit/analyzers/audio_format_profile.py | 3 ++- src/voxkit/analyzers/clip_duration_statistics.py | 3 ++- src/voxkit/analyzers/constants.py | 2 ++ src/voxkit/analyzers/default_analyzer.py | 3 ++- 4 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 src/voxkit/analyzers/constants.py diff --git a/src/voxkit/analyzers/audio_format_profile.py b/src/voxkit/analyzers/audio_format_profile.py index 4844d81..9118582 100644 --- a/src/voxkit/analyzers/audio_format_profile.py +++ b/src/voxkit/analyzers/audio_format_profile.py @@ -19,6 +19,7 @@ from typing import Any, Dict, List from .base import DatasetAnalyzer +from .constants import SUPERSET_AUDIO_EXTENSIONS logger = logging.getLogger(__name__) @@ -38,7 +39,7 @@ def analyze(self, dataset_path: str) -> List[Dict[str, Any]]: import torchaudio results = [] - audio_extensions = {".wav", ".flac", ".mp3", ".ogg", ".m4a"} + audio_extensions = SUPERSET_AUDIO_EXTENSIONS try: for entry in os.scandir(dataset_path): diff --git a/src/voxkit/analyzers/clip_duration_statistics.py b/src/voxkit/analyzers/clip_duration_statistics.py index 5f8d259..55427a7 100644 --- a/src/voxkit/analyzers/clip_duration_statistics.py +++ b/src/voxkit/analyzers/clip_duration_statistics.py @@ -18,6 +18,7 @@ from typing import Any, Dict, List from .base import DatasetAnalyzer +from .constants import SUPERSET_AUDIO_EXTENSIONS logger = logging.getLogger(__name__) @@ -37,7 +38,7 @@ def analyze(self, dataset_path: str) -> List[Dict[str, Any]]: import torchaudio results = [] - audio_extensions = {".wav", ".flac", ".mp3", ".ogg", ".m4a"} + audio_extensions = SUPERSET_AUDIO_EXTENSIONS try: for entry in os.scandir(dataset_path): diff --git a/src/voxkit/analyzers/constants.py b/src/voxkit/analyzers/constants.py new file mode 100644 index 0000000..f3c7bd5 --- /dev/null +++ b/src/voxkit/analyzers/constants.py @@ -0,0 +1,2 @@ +# Full set of audio extensions allowed for datasets +SUPERSET_AUDIO_EXTENSIONS = {".wav", ".flac", ".mp3", ".ogg", ".m4a"} diff --git a/src/voxkit/analyzers/default_analyzer.py b/src/voxkit/analyzers/default_analyzer.py index d9b7383..196ff99 100644 --- a/src/voxkit/analyzers/default_analyzer.py +++ b/src/voxkit/analyzers/default_analyzer.py @@ -18,6 +18,7 @@ from typing import Any, Dict, List from .base import DatasetAnalyzer +from .constants import SUPERSET_AUDIO_EXTENSIONS class DefaultAnalyzer(DatasetAnalyzer): @@ -43,7 +44,7 @@ def analyze(self, dataset_path: str) -> List[Dict[str, Any]]: ``audio_file_count``. """ results = [] - audio_extensions = {".wav", ".flac", ".mp3", ".ogg", ".m4a"} + audio_extensions = SUPERSET_AUDIO_EXTENSIONS try: for entry in os.scandir(dataset_path): From b1ccbceba04a806c833c54667e5c513393ebd234 Mon Sep 17 00:00:00 2001 From: Beckett Frey Date: Thu, 21 May 2026 08:24:24 -0700 Subject: [PATCH 02/10] Move possible tools of an engine to shared constant --- src/voxkit/engines/__init__.py | 9 +++++---- src/voxkit/engines/constants.py | 4 ++++ 2 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 src/voxkit/engines/constants.py diff --git a/src/voxkit/engines/__init__.py b/src/voxkit/engines/__init__.py index 04d5aed..2b2ecde 100644 --- a/src/voxkit/engines/__init__.py +++ b/src/voxkit/engines/__init__.py @@ -6,7 +6,7 @@ - **EngineManager.list_engines**: List registered engine IDs - **EngineManager.get_engine**: Retrieve engine instance by ID - **EngineManager.get_tool_providers**: Get engines providing a specific tool type -- **ToolType**: Literal type for compatible tool types +- **AVAILABLE_TOOLS**: Literal type for compatible tool types Available Engines ----------------- @@ -48,7 +48,8 @@ from typing import List -from .base import AlignmentEngine, ToolType +from .base import AlignmentEngine +from .constants import AVAILABLE_TOOLS from .faster_whisper_engine import FasterWhisperEngine from .mfa_engine import MFAEngine from .w2tg_engine import W2TGEngine @@ -82,7 +83,7 @@ def get_engine(self, engine_id: str) -> AlignmentEngine: except KeyError: raise ValueError(f"No engine with id: {engine_id}") - def get_tool_providers(self, tool: ToolType) -> dict[str, AlignmentEngine]: + def get_tool_providers(self, tool: AVAILABLE_TOOLS) -> dict[str, AlignmentEngine]: """Return a list of engines that provide the specified tool type.""" engines = {} for _, engine in self._engines.items(): @@ -97,4 +98,4 @@ def get_tool_providers(self, tool: ToolType) -> dict[str, AlignmentEngine]: faster_whisper = FasterWhisperEngine(id="FASTERWHISPERENGINE") engines = EngineManager({mfa.id: mfa, faster_whisper.id: faster_whisper, w2tg.id: w2tg}) -__all__ = ["engines", "ToolType"] +__all__ = ["engines", "AVAILABLE_TOOLS"] diff --git a/src/voxkit/engines/constants.py b/src/voxkit/engines/constants.py new file mode 100644 index 0000000..ac8429d --- /dev/null +++ b/src/voxkit/engines/constants.py @@ -0,0 +1,4 @@ +from typing import Literal + +# New engines can implement these tools or a subset of them +AVAILABLE_TOOLS = Literal["train", "align", "transcribe"] From cf129376c37454ce49ff55d7bbfca5071d2f364f Mon Sep 17 00:00:00 2001 From: Beckett Frey Date: Thu, 21 May 2026 09:08:09 -0700 Subject: [PATCH 03/10] Move audio types to storage instead --- src/voxkit/analyzers/audio_format_profile.py | 3 ++- .../analyzers/clip_duration_statistics.py | 3 ++- src/voxkit/analyzers/constants.py | 2 -- src/voxkit/analyzers/default_analyzer.py | 3 ++- src/voxkit/config/startup_config.py | 2 +- .../gui/pages/pipeline/viewer_stacker.py | 3 ++- src/voxkit/storage/alignments.py | 4 ++-- src/voxkit/storage/config.py | 20 ------------------ src/voxkit/storage/constants.py | 21 +++++++++++++++++++ src/voxkit/storage/datasets.py | 6 ++---- src/voxkit/storage/models.py | 2 +- src/voxkit/storage/utils.py | 2 +- tests/engines/test_engine_manager.py | 2 +- tests/storage/test_models.py | 6 +++--- tests/storage/test_setup.py | 2 +- 15 files changed, 41 insertions(+), 40 deletions(-) delete mode 100644 src/voxkit/analyzers/constants.py delete mode 100644 src/voxkit/storage/config.py create mode 100644 src/voxkit/storage/constants.py diff --git a/src/voxkit/analyzers/audio_format_profile.py b/src/voxkit/analyzers/audio_format_profile.py index 9118582..068d1b1 100644 --- a/src/voxkit/analyzers/audio_format_profile.py +++ b/src/voxkit/analyzers/audio_format_profile.py @@ -18,8 +18,9 @@ from pathlib import Path from typing import Any, Dict, List +from voxkit.storage.constants import SUPERSET_AUDIO_EXTENSIONS + from .base import DatasetAnalyzer -from .constants import SUPERSET_AUDIO_EXTENSIONS logger = logging.getLogger(__name__) diff --git a/src/voxkit/analyzers/clip_duration_statistics.py b/src/voxkit/analyzers/clip_duration_statistics.py index 55427a7..8b5b348 100644 --- a/src/voxkit/analyzers/clip_duration_statistics.py +++ b/src/voxkit/analyzers/clip_duration_statistics.py @@ -17,8 +17,9 @@ from pathlib import Path from typing import Any, Dict, List +from voxkit.storage.constants import SUPERSET_AUDIO_EXTENSIONS + from .base import DatasetAnalyzer -from .constants import SUPERSET_AUDIO_EXTENSIONS logger = logging.getLogger(__name__) diff --git a/src/voxkit/analyzers/constants.py b/src/voxkit/analyzers/constants.py deleted file mode 100644 index f3c7bd5..0000000 --- a/src/voxkit/analyzers/constants.py +++ /dev/null @@ -1,2 +0,0 @@ -# Full set of audio extensions allowed for datasets -SUPERSET_AUDIO_EXTENSIONS = {".wav", ".flac", ".mp3", ".ogg", ".m4a"} diff --git a/src/voxkit/analyzers/default_analyzer.py b/src/voxkit/analyzers/default_analyzer.py index 196ff99..c7ab6b5 100644 --- a/src/voxkit/analyzers/default_analyzer.py +++ b/src/voxkit/analyzers/default_analyzer.py @@ -17,8 +17,9 @@ from pathlib import Path from typing import Any, Dict, List +from voxkit.storage.constants import SUPERSET_AUDIO_EXTENSIONS + from .base import DatasetAnalyzer -from .constants import SUPERSET_AUDIO_EXTENSIONS class DefaultAnalyzer(DatasetAnalyzer): diff --git a/src/voxkit/config/startup_config.py b/src/voxkit/config/startup_config.py index 6bd2491..9184acc 100644 --- a/src/voxkit/config/startup_config.py +++ b/src/voxkit/config/startup_config.py @@ -3,7 +3,7 @@ from voxkit.services.mfa import download_acoustic_model from voxkit.storage import models -from voxkit.storage.config import MODELS_ROOT +from voxkit.storage.constants import MODELS_ROOT from voxkit.storage.models import download_and_copy_huggingface_model from voxkit.storage.utils import get_storage_root diff --git a/src/voxkit/gui/pages/pipeline/viewer_stacker.py b/src/voxkit/gui/pages/pipeline/viewer_stacker.py index 293b7c9..b39eef5 100644 --- a/src/voxkit/gui/pages/pipeline/viewer_stacker.py +++ b/src/voxkit/gui/pages/pipeline/viewer_stacker.py @@ -40,6 +40,7 @@ from voxkit.gui.pages.pipeline.base_stacker import BaseStacker from voxkit.gui.styles import Buttons, Colors, Containers, Labels from voxkit.storage import alignments, datasets +from voxkit.storage.constants import SUPERSET_AUDIO_EXTENSIONS if TYPE_CHECKING: from PyQt6.QtMultimedia import QAudioOutput, QMediaPlayer @@ -52,7 +53,7 @@ MULTIMEDIA_AVAILABLE = False -_AUDIO_EXTENSIONS = {".wav", ".flac", ".mp3", ".ogg", ".m4a"} +_AUDIO_EXTENSIONS = SUPERSET_AUDIO_EXTENSIONS _SILENCE_LABELS = {"", "sp", "sil", "", "spn"} # --------------------------------------------------------------------------- diff --git a/src/voxkit/storage/alignments.py b/src/voxkit/storage/alignments.py index 618ca68..dd1cf9a 100644 --- a/src/voxkit/storage/alignments.py +++ b/src/voxkit/storage/alignments.py @@ -38,7 +38,7 @@ from pathlib import Path from typing import List, Literal, Tuple, TypedDict -from .config import ALIGNMENTS_ROOT +from .constants import ALIGNMENTS_ROOT, SUPERSET_AUDIO_EXTENSIONS from .datasets import _get_dataset_root, get_dataset_metadata from .models import ModelMetadata, get_model_metadata from .utils import generate_unique_id, readable_from_unique_id @@ -192,7 +192,7 @@ def create_alignment( return False, f"Failed to create alignment metadata: {str(e)}" -_AUDIO_EXTS = (".wav", ".flac", ".mp3", ".ogg", ".m4a") +_AUDIO_EXTS = SUPERSET_AUDIO_EXTENSIONS def validate_hand_alignments(dataset_path: Path, hand_path: Path) -> Tuple[bool, str]: diff --git a/src/voxkit/storage/config.py b/src/voxkit/storage/config.py deleted file mode 100644 index 9f3312f..0000000 --- a/src/voxkit/storage/config.py +++ /dev/null @@ -1,20 +0,0 @@ -"""This module contains constants for the VoxKit storage system. - -Constants ---------- -- **STORAGE_ROOT**: Root directory for all VoxKit storage (~/.voxkit) -- **MODELS_ROOT**: Subdirectory for model storage relative to engine directory -- **DATASETS_ROOT**: Subdirectory for dataset storage relative to STORAGE_ROOT -- **ALIGNMENTS_ROOT**: Subdirectory for alignments relative to dataset directory - -Notes ------ -- STORAGE_ROOT uses tilde (~) notation to reference the user's home directory -- All paths are relative to appropriate parent directories in the hierarchy -- The directory structure is created automatically on first use -""" - -STORAGE_ROOT = "~/.voxkit" # Root directory for all storage -MODELS_ROOT = "train" # Path from STORAGE_ROOT to models -DATASETS_ROOT = "datasets" # Path from STORAGE_ROOT to datasets -ALIGNMENTS_ROOT = "alignments" # Path from STORAGE_ROOT/DATASETS_ROOT to alignments diff --git a/src/voxkit/storage/constants.py b/src/voxkit/storage/constants.py new file mode 100644 index 0000000..0fe2639 --- /dev/null +++ b/src/voxkit/storage/constants.py @@ -0,0 +1,21 @@ +"""This module contains constants for the VoxKit storage layer. + +Constants +--------- +- **STORAGE_ROOT**: Root directory for all VoxKit storage (~/.voxkit) +- **MODELS_ROOT**: Subdirectory for model storage relative to engine directory +- **DATASETS_ROOT**: Subdirectory for dataset storage relative to STORAGE_ROOT +- **ALIGNMENTS_ROOT**: Subdirectory for alignments relative to dataset directory +- **SUPERSET_AUDIO_EXTENSIONS**: Comprehensive set of audio file extensions + +Notes +----- +- STORAGE_ROOT uses tilde (~) notation to reference the user's home directory +- All paths are relative to appropriate parent directories in the hierarchy +""" + +STORAGE_ROOT: str = "~/.voxkit" # Root directory for all storage +MODELS_ROOT: str = "train" # Path from STORAGE_ROOT to models +DATASETS_ROOT: str = "datasets" # Path from STORAGE_ROOT to datasets +ALIGNMENTS_ROOT: str = "alignments" # Path from STORAGE_ROOT/DATASETS_ROOT to alignments +SUPERSET_AUDIO_EXTENSIONS: set[str] = {".wav", ".flac", ".mp3", ".ogg", ".m4a"} diff --git a/src/voxkit/storage/datasets.py b/src/voxkit/storage/datasets.py index 2017112..b67a8fb 100644 --- a/src/voxkit/storage/datasets.py +++ b/src/voxkit/storage/datasets.py @@ -43,7 +43,7 @@ from pathlib import Path from typing import Any, List, Literal, Tuple, TypedDict -from voxkit.storage.config import ALIGNMENTS_ROOT, DATASETS_ROOT +from voxkit.storage.constants import ALIGNMENTS_ROOT, DATASETS_ROOT, SUPERSET_AUDIO_EXTENSIONS from voxkit.storage.utils import generate_unique_id, get_storage_root, readable_from_unique_id @@ -627,9 +627,7 @@ def validate_dataset(dataset_path: Path, transcribed: bool = True) -> Tuple[bool for speaker in speaker_dirs: speaker_path = os.path.join(dataset_path, speaker) audio_files = [ - f - for f in os.listdir(speaker_path) - if f.endswith((".wav", ".flac", ".mp3", ".ogg", ".m4a")) + f for f in os.listdir(speaker_path) if f.endswith(tuple(SUPERSET_AUDIO_EXTENSIONS)) ] if not audio_files: diff --git a/src/voxkit/storage/models.py b/src/voxkit/storage/models.py index b197e94..93e4a79 100644 --- a/src/voxkit/storage/models.py +++ b/src/voxkit/storage/models.py @@ -40,7 +40,7 @@ from voxkit.storage.utils import generate_unique_id, get_storage_root, readable_from_unique_id -from .config import MODELS_ROOT +from .constants import MODELS_ROOT class ModelMetadata(TypedDict): diff --git a/src/voxkit/storage/utils.py b/src/voxkit/storage/utils.py index 3f25184..7a297a5 100644 --- a/src/voxkit/storage/utils.py +++ b/src/voxkit/storage/utils.py @@ -25,7 +25,7 @@ from pathlib import Path from typing import Any -from .config import STORAGE_ROOT +from .constants import STORAGE_ROOT _id_lock = threading.Lock() _last_id_dt: datetime | None = None diff --git a/tests/engines/test_engine_manager.py b/tests/engines/test_engine_manager.py index 1356ea0..93318e4 100644 --- a/tests/engines/test_engine_manager.py +++ b/tests/engines/test_engine_manager.py @@ -35,7 +35,7 @@ def test_get_engine_not_found(self): assert "No engine with id" in str(exc_info.value) def test_get_tool_providers_align(self): - # ToolType is Literal["train", "align", "transcribe"] + # AVAILABLE_TOOLS is Literal["train", "align", "transcribe"] providers = engines.get_tool_providers("align") assert isinstance(providers, dict) # At least some engines should provide alignment diff --git a/tests/storage/test_models.py b/tests/storage/test_models.py index 95f325b..17ee9ba 100644 --- a/tests/storage/test_models.py +++ b/tests/storage/test_models.py @@ -631,7 +631,7 @@ def test_import_models_success(self, monkeypatch): import json from voxkit.storage import models - from voxkit.storage.config import MODELS_ROOT + from voxkit.storage.constants import MODELS_ROOT from voxkit.storage.models import import_models monkeypatch.setattr(models, "get_storage_root", mock_get_storage_root) @@ -674,7 +674,7 @@ def test_import_models_paths_rewritten(self, monkeypatch): import json from voxkit.storage import models - from voxkit.storage.config import MODELS_ROOT + from voxkit.storage.constants import MODELS_ROOT from voxkit.storage.models import import_models, list_models monkeypatch.setattr(models, "get_storage_root", mock_get_storage_root) @@ -737,7 +737,7 @@ def test_import_models_engine_mismatch(self, monkeypatch): import json from voxkit.storage import models - from voxkit.storage.config import MODELS_ROOT + from voxkit.storage.constants import MODELS_ROOT from voxkit.storage.models import import_models monkeypatch.setattr(models, "get_storage_root", mock_get_storage_root) diff --git a/tests/storage/test_setup.py b/tests/storage/test_setup.py index aee3508..ba6f518 100644 --- a/tests/storage/test_setup.py +++ b/tests/storage/test_setup.py @@ -1,7 +1,7 @@ import shutil from pathlib import Path -from voxkit.storage.config import MODELS_ROOT +from voxkit.storage.constants import MODELS_ROOT ENGINE_IDS = ["ENGINE_A", "ENGINE_B", "ENGINE_C"] From d10579004e9b8d01af6ea61728b8e70b015b3a8f Mon Sep 17 00:00:00 2001 From: Beckett Frey Date: Thu, 21 May 2026 09:45:03 -0700 Subject: [PATCH 04/10] Move help url to shared constants instead --- src/voxkit/config/__init__.py | 4 ++-- src/voxkit/config/app_config.py | 6 ++++-- src/voxkit/config/constants.py | 8 ++++++++ src/voxkit/config/startup_config.py | 1 - tests/config/test_app_config.py | 2 +- 5 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 src/voxkit/config/constants.py diff --git a/src/voxkit/config/__init__.py b/src/voxkit/config/__init__.py index 0cc437e..b1a6203 100644 --- a/src/voxkit/config/__init__.py +++ b/src/voxkit/config/__init__.py @@ -28,6 +28,7 @@ get_profile_config_path, resolve_config_file, ) +from voxkit.config.constants import DEFAULT_HELP_URL from voxkit.config.logging_config import ( LOG_FILE, reset_logging, @@ -40,7 +41,6 @@ get_pipeline_config, ) from voxkit.config.startup_config import ( - HELP_URL, STARTUP_SCRIPT, AppName, Defaults, @@ -63,7 +63,7 @@ "UIConfig", "get_pipeline_config", # Startup config - "HELP_URL", + "DEFAULT_HELP_URL", "AppName", "Dimensions", "Defaults", diff --git a/src/voxkit/config/app_config.py b/src/voxkit/config/app_config.py index 3201aff..96f5c71 100644 --- a/src/voxkit/config/app_config.py +++ b/src/voxkit/config/app_config.py @@ -14,6 +14,8 @@ import yaml +from voxkit.config.constants import DEFAULT_HELP_URL + def get_config_root() -> Path: """Get the path to the config root directory. @@ -128,7 +130,7 @@ class AppConfig: version: str description: str introduction: str - help_url: str = "https://voxkit-web.vercel.app/help" + help_url: str | None = None release_date: Optional[str] = None release_notes: Optional[str] = None log_max_bytes: int = 5 * 1024 * 1024 @@ -164,7 +166,7 @@ def from_yaml(cls, config_path: Path) -> "AppConfig": version=version, description=data.get("description", ""), introduction=data.get("introduction", ""), - help_url=data.get("help_url", "https://voxkit-web.vercel.app/help"), + help_url=data.get("help_url", DEFAULT_HELP_URL), release_date=data.get("release_date"), release_notes=data.get("release_notes"), log_max_bytes=int(data.get("log_max_bytes", 5 * 1024 * 1024)), diff --git a/src/voxkit/config/constants.py b/src/voxkit/config/constants.py new file mode 100644 index 0000000..65ed8f4 --- /dev/null +++ b/src/voxkit/config/constants.py @@ -0,0 +1,8 @@ +"""Constants relevant to configuration and setup. + +Constants +--------- +- **DEFAULT_HELP_URL**: URL for user help documentation +""" + +DEFAULT_HELP_URL = "https://voxkit-web.vercel.app/help" diff --git a/src/voxkit/config/startup_config.py b/src/voxkit/config/startup_config.py index 9184acc..334c520 100644 --- a/src/voxkit/config/startup_config.py +++ b/src/voxkit/config/startup_config.py @@ -18,7 +18,6 @@ } Mode = Literal["MFAENGINE", "W2TGENGINE"] -HELP_URL = "https://voxkit-web.vercel.app/help" def startup_routine(): diff --git a/tests/config/test_app_config.py b/tests/config/test_app_config.py index 1bb288d..2ce9ddf 100644 --- a/tests/config/test_app_config.py +++ b/tests/config/test_app_config.py @@ -52,7 +52,7 @@ def test_dataclass_fields(self): assert config.version == "1.0.0" assert config.description == "Test description" assert config.introduction == "Test intro" - assert config.help_url == "https://voxkit-web.vercel.app/help" + assert config.help_url is None config = AppConfig( app_name="TestApp", version="2.0.0", From e18d883bb41e66630fc44312f6028f0ee536d800 Mon Sep 17 00:00:00 2001 From: Beckett Frey Date: Thu, 21 May 2026 10:19:15 -0700 Subject: [PATCH 05/10] Remove deprecated function get_profile_config --- src/voxkit/config/app_config.py | 19 +------------------ tests/config/test_app_config.py | 5 ----- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/src/voxkit/config/app_config.py b/src/voxkit/config/app_config.py index 96f5c71..eb7ab76 100644 --- a/src/voxkit/config/app_config.py +++ b/src/voxkit/config/app_config.py @@ -98,30 +98,13 @@ def resolve_config_file(filename: str) -> Path: if default_path.exists(): return default_path - # Fall back to legacy location (config root) - legacy_path = config_root / filename - if legacy_path.exists(): - return legacy_path - + # Throw error if not found in either location raise FileNotFoundError( f"Config file '{filename}' not found in profile '{profile}', " f"default profile, or config root" ) -# Legacy alias for backwards compatibility -def get_config_path() -> Path: - """Get the path to the config directory. - - Deprecated: Use get_profile_config_path() for profile-aware loading, - or get_config_root() for the config root directory. - - Returns: - Path to the active profile's config directory - """ - return get_profile_config_path() - - @dataclass class AppConfig: """Application configuration data class.""" diff --git a/tests/config/test_app_config.py b/tests/config/test_app_config.py index 2ce9ddf..bb72ebe 100644 --- a/tests/config/test_app_config.py +++ b/tests/config/test_app_config.py @@ -6,7 +6,6 @@ AppConfig, get_active_profile, get_app_config, - get_config_path, get_config_root, get_profile_config_path, ) @@ -35,10 +34,6 @@ def test_get_profile_config_path_is_inside_profiles(self): # Should be config/profiles/ assert result.parent.name == "profiles" - def test_get_config_path_is_alias_for_profile_path(self): - # get_config_path is now an alias for get_profile_config_path - assert get_config_path() == get_profile_config_path() - class TestAppConfig: def test_dataclass_fields(self): From 7df8f9840cfe58178ecb671d12192e0fcfc9c953 Mon Sep 17 00:00:00 2001 From: Beckett Frey Date: Thu, 21 May 2026 10:39:21 -0700 Subject: [PATCH 06/10] Reformat badges in readme ocd --- README.md | 36 ++++++++---------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 2cbaaed..fa6742b 100644 --- a/README.md +++ b/README.md @@ -3,37 +3,17 @@

- - Release - - - Downloads - - Coverage + Release + Downloads + ShredGuard + Jira

- - ShredGuard - -

- -

- - Ubuntu Tests - - - macOS Tests - - - Windows Tests - - - Code Quality - - - Jira - + Ubuntu Tests + macOS Tests + Windows Tests + Code Quality

> [!IMPORTANT] From d7b75cf40946730b6313d4204b27aa762fc718d0 Mon Sep 17 00:00:00 2001 From: Beckett <83560790+BeckettFrey@users.noreply.github.com> Date: Thu, 21 May 2026 11:14:54 -0700 Subject: [PATCH 07/10] Copilot fix Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/voxkit/config/app_config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/voxkit/config/app_config.py b/src/voxkit/config/app_config.py index eb7ab76..93280b6 100644 --- a/src/voxkit/config/app_config.py +++ b/src/voxkit/config/app_config.py @@ -100,8 +100,8 @@ def resolve_config_file(filename: str) -> Path: # Throw error if not found in either location raise FileNotFoundError( - f"Config file '{filename}' not found in profile '{profile}', " - f"default profile, or config root" + f"Config file '{filename}' not found in profile '{profile}' " + f"or default profile" ) From 702279af9252814d1ef0958316947a31d7d542ee Mon Sep 17 00:00:00 2001 From: Beckett Frey Date: Thu, 21 May 2026 11:20:58 -0700 Subject: [PATCH 08/10] Match constant to duplicate definition per feedback --- src/voxkit/engines/base.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/voxkit/engines/base.py b/src/voxkit/engines/base.py index ae34871..bc23134 100644 --- a/src/voxkit/engines/base.py +++ b/src/voxkit/engines/base.py @@ -32,8 +32,9 @@ def align(self, dataset_id: str, model_id: str) -> None: import json from abc import ABC, abstractmethod from pathlib import Path -from typing import Any, Literal +from typing import Any +from voxkit.engines.constants import AVAILABLE_TOOLS from voxkit.storage.utils import get_storage_root """ @@ -42,18 +43,16 @@ def align(self, dataset_id: str, model_id: str) -> None: has its own settings that are stored in a JSON file. """ -ToolType = Literal["train", "align", "transcribe"] - class AlignmentEngine(ABC): """ Abstract base class for alignment engines. - Subclasses must implement at least one ToolType operation and provide + Subclasses must implement at least one AVAILABLE_TOOLS operation and provide specific validation criteria. Attributes: - settings_configurations (dict[ToolType, Any]): Mapping of + settings_configurations (dict[AVAILABLE_TOOLS, Any]): Mapping of tool type names ("train"/"align") to their store configuration. reference_url (str | None): Optional reference URL for the engine. description (str | None): Human-readable description of the engine. @@ -63,7 +62,7 @@ class AlignmentEngine(ABC): def __init__( self, - settings_configurations: dict[ToolType, Any], + settings_configurations: dict[AVAILABLE_TOOLS, Any], reference_url: str | None = None, description: str | None = None, human_readable_name: str | None = None, @@ -218,7 +217,7 @@ def _get_default_settings(self, cfg: Any) -> dict: """ return {field.name: field.default_value for field in (cfg.fields or [])} - def get_settings(self, tool_type: ToolType) -> dict: + def get_settings(self, tool_type: AVAILABLE_TOOLS) -> dict: """ Load and validate settings for a specific tool. @@ -269,7 +268,7 @@ def get_settings(self, tool_type: ToolType) -> dict: return settings - def get_settings_config(self, tool_type: ToolType) -> Any: + def get_settings_config(self, tool_type: AVAILABLE_TOOLS) -> Any: """ Return the :class:`Any` for a tool type. @@ -287,7 +286,7 @@ def get_settings_config(self, tool_type: ToolType) -> Any: raise ValueError(f"No settings configuration found for tool type: {tool_type}") return config - def has_tool(self, tool_type: ToolType) -> bool: + def has_tool(self, tool_type: AVAILABLE_TOOLS) -> bool: """Check if the engine has a tool of the specified type.""" return tool_type in self.settings_configurations From c4edcaf7c50da1b75379d703c7fcf7f337187418 Mon Sep 17 00:00:00 2001 From: Beckett <83560790+BeckettFrey@users.noreply.github.com> Date: Thu, 21 May 2026 11:25:04 -0700 Subject: [PATCH 09/10] Copilot feedback Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/voxkit/storage/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/voxkit/storage/constants.py b/src/voxkit/storage/constants.py index 0fe2639..6270649 100644 --- a/src/voxkit/storage/constants.py +++ b/src/voxkit/storage/constants.py @@ -18,4 +18,4 @@ MODELS_ROOT: str = "train" # Path from STORAGE_ROOT to models DATASETS_ROOT: str = "datasets" # Path from STORAGE_ROOT to datasets ALIGNMENTS_ROOT: str = "alignments" # Path from STORAGE_ROOT/DATASETS_ROOT to alignments -SUPERSET_AUDIO_EXTENSIONS: set[str] = {".wav", ".flac", ".mp3", ".ogg", ".m4a"} +SUPERSET_AUDIO_EXTENSIONS: frozenset[str] = frozenset({".wav", ".flac", ".mp3", ".ogg", ".m4a"}) From dd424c4b03c14603ed534fd46d20afa7744ef95f Mon Sep 17 00:00:00 2001 From: Beckett Frey Date: Thu, 21 May 2026 11:29:48 -0700 Subject: [PATCH 10/10] Lint code [skip ci] --- src/voxkit/config/app_config.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/voxkit/config/app_config.py b/src/voxkit/config/app_config.py index 93280b6..aa46fe4 100644 --- a/src/voxkit/config/app_config.py +++ b/src/voxkit/config/app_config.py @@ -100,8 +100,7 @@ def resolve_config_file(filename: str) -> Path: # Throw error if not found in either location raise FileNotFoundError( - f"Config file '{filename}' not found in profile '{profile}' " - f"or default profile" + f"Config file '{filename}' not found in profile '{profile}' or default profile" )