refs #701: load console profile overrides from dotenv
This commit is contained in:
@@ -6921,7 +6921,7 @@ def _process_submitted_question(
|
|||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
try:
|
try:
|
||||||
profile = load_app_profile(APP_PROFILE_FILE)
|
profile = load_app_profile(APP_PROFILE_FILE, ENV_FILE)
|
||||||
except AppProfileError as exc:
|
except AppProfileError as exc:
|
||||||
st.set_page_config(page_title="AI 업무 에이전트", layout="wide")
|
st.set_page_config(page_title="AI 업무 에이전트", layout="wide")
|
||||||
st.error(str(exc))
|
st.error(str(exc))
|
||||||
|
|||||||
@@ -61,17 +61,38 @@ def resolve_profile_path(default_path: Path) -> Path:
|
|||||||
return path if path.is_absolute() else default_path.parent / path
|
return path if path.is_absolute() else default_path.parent / path
|
||||||
|
|
||||||
|
|
||||||
def _apply_environment_overrides(profile: AppProfile) -> AppProfile:
|
def _dotenv_value(name: str, path: Path | None) -> str:
|
||||||
|
"""Read one simple KEY=value runtime setting without importing a dotenv lib."""
|
||||||
|
|
||||||
|
if path is None:
|
||||||
|
return ""
|
||||||
|
try:
|
||||||
|
lines = path.read_text(encoding="utf-8").splitlines()
|
||||||
|
except (OSError, UnicodeError):
|
||||||
|
return ""
|
||||||
|
prefix = f"{name}="
|
||||||
|
for line in lines:
|
||||||
|
stripped = line.strip()
|
||||||
|
if stripped.startswith(prefix):
|
||||||
|
return stripped[len(prefix) :].strip().strip('"').strip("'")
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def _apply_environment_overrides(profile: AppProfile, env_file: Path | None) -> AppProfile:
|
||||||
"""Apply deployment-specific presentation values without a code change."""
|
"""Apply deployment-specific presentation values without a code change."""
|
||||||
|
|
||||||
values = {
|
values = {
|
||||||
field_name: os.environ.get(env_name, "").strip() or getattr(profile, field_name)
|
field_name: (
|
||||||
|
os.environ.get(env_name, "").strip()
|
||||||
|
or _dotenv_value(env_name, env_file)
|
||||||
|
or getattr(profile, field_name)
|
||||||
|
)
|
||||||
for field_name, env_name in _ENV_FIELD_NAMES.items()
|
for field_name, env_name in _ENV_FIELD_NAMES.items()
|
||||||
}
|
}
|
||||||
return AppProfile(**values)
|
return AppProfile(**values)
|
||||||
|
|
||||||
|
|
||||||
def load_app_profile(default_path: Path) -> AppProfile:
|
def load_app_profile(default_path: Path, env_file: Path | None = None) -> AppProfile:
|
||||||
"""Load the selectable product skin without coupling it to a PoC name."""
|
"""Load the selectable product skin without coupling it to a PoC name."""
|
||||||
|
|
||||||
path = resolve_profile_path(default_path)
|
path = resolve_profile_path(default_path)
|
||||||
@@ -101,7 +122,7 @@ def load_app_profile(default_path: Path) -> AppProfile:
|
|||||||
text_color=_string(theme, "text_color"),
|
text_color=_string(theme, "text_color"),
|
||||||
muted_color=_string(theme, "muted_color"),
|
muted_color=_string(theme, "muted_color"),
|
||||||
border_color=_string(theme, "border_color"),
|
border_color=_string(theme, "border_color"),
|
||||||
))
|
), env_file)
|
||||||
required = (
|
required = (
|
||||||
profile.product_name,
|
profile.product_name,
|
||||||
profile.short_name,
|
profile.short_name,
|
||||||
|
|||||||
@@ -28,6 +28,15 @@ class DemoScenarioConfigTest(unittest.TestCase):
|
|||||||
self.assertEqual(profile.page_title, "HMM AI 업무 에이전트")
|
self.assertEqual(profile.page_title, "HMM AI 업무 에이전트")
|
||||||
self.assertEqual(profile.primary_color, "#003b70")
|
self.assertEqual(profile.primary_color, "#003b70")
|
||||||
|
|
||||||
|
def test_profile_reads_dotenv_values(self) -> None:
|
||||||
|
path = Path(__file__).parents[1] / "config" / "app_profile.json"
|
||||||
|
with tempfile.TemporaryDirectory() as temp_dir:
|
||||||
|
env_file = Path(temp_dir) / ".env"
|
||||||
|
env_file.write_text("AGENT_CONSOLE_SHORT_NAME=HMM\n", encoding="utf-8")
|
||||||
|
profile = load_app_profile(path, env_file)
|
||||||
|
|
||||||
|
self.assertEqual(profile.short_name, "HMM")
|
||||||
|
|
||||||
def test_hmm_scenarios_are_enabled_and_unique(self) -> None:
|
def test_hmm_scenarios_are_enabled_and_unique(self) -> None:
|
||||||
path = Path(__file__).parents[1] / "config" / "hmm_demo_scenarios.json"
|
path = Path(__file__).parents[1] / "config" / "hmm_demo_scenarios.json"
|
||||||
scenarios = load_demo_scenarios(path)
|
scenarios = load_demo_scenarios(path)
|
||||||
|
|||||||
Reference in New Issue
Block a user