[配置]:完成 .env 文件读取配置,包含自动加载、CLI 参数、测试覆盖和中文说明

This commit is contained in:
mkbk
2026-06-17 18:59:11 +08:00
parent 9729969915
commit 61abf0c674
5 changed files with 78 additions and 20 deletions
+13
View File
@@ -27,6 +27,19 @@ class CliAcceptanceTests(unittest.TestCase):
self.assertEqual(code, 0)
self.assertTrue(data["valid"])
def test_show_config_reads_env_file_without_printing_secret(self) -> None:
import tempfile
with tempfile.TemporaryDirectory() as tmp:
path = f"{tmp}/.env"
with open(path, "w", encoding="utf-8") as handle:
handle.write("OWNER_LLM_API_KEY=secret-value\nOWNER_LLM_MODEL=file-model\n")
code, data = self.call("--env-file", path, "--show-config")
self.assertEqual(code, 0)
self.assertTrue(data["llm_api_key_present"])
self.assertEqual(data["llm_model"], "file-model")
self.assertNotIn("secret-value", str(data))
def test_security_check_command_has_no_leaks(self) -> None:
code, data = self.call("security-check")
self.assertEqual(code, 0)
+20 -11
View File
@@ -1,6 +1,6 @@
from __future__ import annotations
import os
import tempfile
import unittest
from owner_voice_pet.config import AppConfig
@@ -52,21 +52,30 @@ class ModelsConfigTests(unittest.TestCase):
self.assertIn("LLM_API_KEY_MISSING", str(error))
self.assertIn("llm/openai-compatible", str(error))
def test_config_from_env_masks_secret_boundary(self) -> None:
old_env = dict(os.environ)
try:
os.environ["OWNER_LLM_BASE_URL"] = "https://newapi.mkbk.shop/"
os.environ["OWNER_LLM_API_KEY"] = "secret-value"
os.environ["OWNER_LLM_MODEL"] = "test-model"
config = AppConfig.from_env()
def test_config_from_dotenv_uses_file_values(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
path = f"{tmp}/.env"
with open(path, "w", encoding="utf-8") as handle:
handle.write(
"\n".join(
[
"OWNER_LLM_BASE_URL=https://newapi.mkbk.shop/",
"OWNER_LLM_API_KEY=secret-value",
"OWNER_LLM_MODEL=test-model",
]
)
)
config = AppConfig.from_dotenv(path)
self.assertEqual(config.llm_base_url, "https://newapi.mkbk.shop")
self.assertEqual(config.llm_api_key, "secret-value")
self.assertEqual(config.llm_model, "test-model")
self.assertTrue(config.llm_stream)
self.assertEqual(config.validate_basic(), [])
finally:
os.environ.clear()
os.environ.update(old_env)
def test_missing_dotenv_uses_non_secret_defaults(self) -> None:
config = AppConfig.from_dotenv("/tmp/owner-voice-pet-missing.env")
self.assertEqual(config.llm_base_url, "https://newapi.mkbk.shop")
self.assertIsNone(config.llm_api_key)
def test_missing_llm_key_has_structured_error(self) -> None:
config = AppConfig(llm_api_key=None)