feat: add config module with TOML loading and defaults
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
# ~/.config/whisper-local/config.toml
|
||||||
|
|
||||||
|
[hotkey]
|
||||||
|
key = "KEY_F12"
|
||||||
|
|
||||||
|
[whisper]
|
||||||
|
model = "small"
|
||||||
|
language = "de"
|
||||||
|
compute_type = "int8"
|
||||||
|
|
||||||
|
[audio]
|
||||||
|
sample_rate = 16000
|
||||||
|
channels = 1
|
||||||
|
min_duration = 0.5
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
import tomllib
|
||||||
|
|
||||||
|
from whisper_local.config import Config, load_config
|
||||||
|
|
||||||
|
|
||||||
|
class TestConfigDefaults:
|
||||||
|
def test_default_hotkey(self):
|
||||||
|
config = Config()
|
||||||
|
assert config.hotkey == "KEY_F12"
|
||||||
|
|
||||||
|
def test_default_whisper_model(self):
|
||||||
|
config = Config()
|
||||||
|
assert config.whisper_model == "small"
|
||||||
|
|
||||||
|
def test_default_language(self):
|
||||||
|
config = Config()
|
||||||
|
assert config.language == "de"
|
||||||
|
|
||||||
|
def test_default_compute_type(self):
|
||||||
|
config = Config()
|
||||||
|
assert config.compute_type == "int8"
|
||||||
|
|
||||||
|
def test_default_sample_rate(self):
|
||||||
|
config = Config()
|
||||||
|
assert config.sample_rate == 16000
|
||||||
|
|
||||||
|
def test_default_channels(self):
|
||||||
|
config = Config()
|
||||||
|
assert config.channels == 1
|
||||||
|
|
||||||
|
def test_default_min_duration(self):
|
||||||
|
config = Config()
|
||||||
|
assert config.min_duration == 0.5
|
||||||
|
|
||||||
|
|
||||||
|
class TestLoadConfig:
|
||||||
|
def test_load_from_toml(self, tmp_path):
|
||||||
|
config_file = tmp_path / "config.toml"
|
||||||
|
config_file.write_text(
|
||||||
|
'[hotkey]\nkey = "KEY_F8"\n\n'
|
||||||
|
'[whisper]\nmodel = "tiny"\nlanguage = "en"\n'
|
||||||
|
)
|
||||||
|
config = load_config(config_file)
|
||||||
|
assert config.hotkey == "KEY_F8"
|
||||||
|
assert config.whisper_model == "tiny"
|
||||||
|
assert config.language == "en"
|
||||||
|
# Defaults bleiben erhalten
|
||||||
|
assert config.compute_type == "int8"
|
||||||
|
|
||||||
|
def test_load_nonexistent_returns_defaults(self, tmp_path):
|
||||||
|
config = load_config(tmp_path / "nope.toml")
|
||||||
|
assert config.hotkey == "KEY_F12"
|
||||||
|
|
||||||
|
def test_load_empty_file(self, tmp_path):
|
||||||
|
config_file = tmp_path / "config.toml"
|
||||||
|
config_file.write_text("")
|
||||||
|
config = load_config(config_file)
|
||||||
|
assert config.hotkey == "KEY_F12"
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
"""Konfiguration aus TOML-Datei mit sinnvollen Defaults."""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from pathlib import Path
|
||||||
|
import tomllib
|
||||||
|
|
||||||
|
|
||||||
|
DEFAULT_CONFIG_PATH = Path.home() / ".config" / "whisper-local" / "config.toml"
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Config:
|
||||||
|
hotkey: str = "KEY_F12"
|
||||||
|
whisper_model: str = "small"
|
||||||
|
language: str = "de"
|
||||||
|
compute_type: str = "int8"
|
||||||
|
sample_rate: int = 16000
|
||||||
|
channels: int = 1
|
||||||
|
min_duration: float = 0.5
|
||||||
|
|
||||||
|
|
||||||
|
def load_config(path: Path = DEFAULT_CONFIG_PATH) -> Config:
|
||||||
|
"""Lädt Config aus TOML-Datei. Gibt Defaults zurück wenn Datei fehlt."""
|
||||||
|
config = Config()
|
||||||
|
|
||||||
|
if not path.exists():
|
||||||
|
return config
|
||||||
|
|
||||||
|
with open(path, "rb") as f:
|
||||||
|
data = tomllib.load(f)
|
||||||
|
|
||||||
|
hotkey_section = data.get("hotkey", {})
|
||||||
|
if "key" in hotkey_section:
|
||||||
|
config.hotkey = hotkey_section["key"]
|
||||||
|
|
||||||
|
whisper_section = data.get("whisper", {})
|
||||||
|
if "model" in whisper_section:
|
||||||
|
config.whisper_model = whisper_section["model"]
|
||||||
|
if "language" in whisper_section:
|
||||||
|
config.language = whisper_section["language"]
|
||||||
|
if "compute_type" in whisper_section:
|
||||||
|
config.compute_type = whisper_section["compute_type"]
|
||||||
|
|
||||||
|
audio_section = data.get("audio", {})
|
||||||
|
if "sample_rate" in audio_section:
|
||||||
|
config.sample_rate = audio_section["sample_rate"]
|
||||||
|
if "channels" in audio_section:
|
||||||
|
config.channels = audio_section["channels"]
|
||||||
|
if "min_duration" in audio_section:
|
||||||
|
config.min_duration = audio_section["min_duration"]
|
||||||
|
|
||||||
|
return config
|
||||||
Reference in New Issue
Block a user