From c7ca7099b264d4dd5df94973752d0804d9ab0d53 Mon Sep 17 00:00:00 2001 From: beo3000 Date: Mon, 15 Jun 2026 15:05:55 +0200 Subject: [PATCH] feat(config): load settings from env via pydantic-settings --- src/journal_bot/config.py | 37 +++++++++++++++++++++++++++++++++++++ tests/test_config.py | 27 +++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/journal_bot/config.py create mode 100644 tests/test_config.py diff --git a/src/journal_bot/config.py b/src/journal_bot/config.py new file mode 100644 index 0000000..8ae8e1b --- /dev/null +++ b/src/journal_bot/config.py @@ -0,0 +1,37 @@ +from pathlib import Path +from pydantic import Field +from pydantic_settings import BaseSettings, SettingsConfigDict + + +class Config(BaseSettings): + model_config = SettingsConfigDict(env_file=".env", extra="ignore") + + telegram_token: str = Field(..., alias="TELEGRAM_TOKEN") + allowed_user_id: int = Field(..., alias="ALLOWED_USER_ID") + vault_path: Path = Field(..., alias="VAULT_PATH") + journal_bot_home: Path = Field(..., alias="JOURNAL_BOT_HOME") + + lmstudio_url: str = Field("http://localhost:1234/v1", alias="LMSTUDIO_URL") + lmstudio_model: str = Field("qwen/qwen3-vl-8b", alias="LMSTUDIO_MODEL") + whisper_model: str = Field("large-v3", alias="WHISPER_MODEL") + whisper_device: str = Field("cpu", alias="WHISPER_DEVICE") + + @property + def queue_dir(self) -> Path: + return self.journal_bot_home / "queue" + + @property + def state_dir(self) -> Path: + return self.journal_bot_home / "state" + + @property + def logs_dir(self) -> Path: + return self.journal_bot_home / "logs" + + @property + def attachments_dir(self) -> Path: + return self.vault_path / "07 Anhänge" + + @property + def daily_notes_dir(self) -> Path: + return self.vault_path / "05 Daily Notes" diff --git a/tests/test_config.py b/tests/test_config.py new file mode 100644 index 0000000..84cbfa4 --- /dev/null +++ b/tests/test_config.py @@ -0,0 +1,27 @@ +import os +from pathlib import Path +import pytest +from journal_bot.config import Config + + +def test_config_loads_from_env(monkeypatch, tmp_path): + monkeypatch.setenv("TELEGRAM_TOKEN", "abc") + monkeypatch.setenv("ALLOWED_USER_ID", "42") + monkeypatch.setenv("VAULT_PATH", str(tmp_path)) + monkeypatch.setenv("JOURNAL_BOT_HOME", str(tmp_path / "runtime")) + + cfg = Config() + + assert cfg.telegram_token == "abc" + assert cfg.allowed_user_id == 42 + assert cfg.vault_path == tmp_path + assert cfg.queue_dir == tmp_path / "runtime" / "queue" + assert cfg.state_dir == tmp_path / "runtime" / "state" + assert cfg.logs_dir == tmp_path / "runtime" / "logs" + + +def test_config_missing_required_fails(monkeypatch): + for var in ["TELEGRAM_TOKEN", "ALLOWED_USER_ID", "VAULT_PATH"]: + monkeypatch.delenv(var, raising=False) + with pytest.raises(Exception): + Config()