mistle/mud_env.py
2026-02-09 10:15:12 +01:00

93 lines
2.5 KiB
Python

from __future__ import annotations
import os
from dataclasses import dataclass
from pathlib import Path
@dataclass(frozen=True)
class ConnectionSettings:
host: str
port: int
user: str
password: str
login_prompt: str
exit_command: str
@dataclass(frozen=True)
class ToolSettings:
tool_mode: bool
tool_spec: str
sideload_specs: list[str]
autoplay: bool
def load_env_file(path: str = ".env") -> None:
"""Populate ``os.environ`` with key/value pairs from a dotenv file."""
env_path = Path(path)
if not env_path.exists():
return
for line in env_path.read_text().splitlines():
stripped = line.strip()
if not stripped or stripped.startswith("#"):
continue
if "=" not in stripped:
continue
key, value = stripped.split("=", 1)
key = key.strip()
value = value.strip().strip('"').strip("'")
if key and key not in os.environ:
os.environ[key] = value
def require_env(key: str) -> str:
value = os.environ.get(key)
if value is None:
raise RuntimeError(f"Missing required environment variable: {key}")
return value
def parse_bool(raw: str) -> bool:
return raw.strip().lower() in {"1", "true", "yes", "on"}
def parse_port(raw: str) -> int:
try:
return int(raw)
except ValueError as exc:
raise RuntimeError("MISTLE_PORT must be an integer") from exc
def parse_csv(raw: str) -> list[str]:
return [value.strip() for value in raw.split(",") if value.strip()]
def read_connection_settings() -> ConnectionSettings:
host = require_env("MISTLE_HOST")
port = parse_port(require_env("MISTLE_PORT"))
user = os.environ.get("MISTLE_USER", "")
password = os.environ.get("MISTLE_PASSWORD", "")
login_prompt = os.environ.get("MISTLE_LOGIN_PROMPT", "")
exit_command = os.environ.get("MISTLE_EXIT_COMMAND", "")
return ConnectionSettings(
host=host,
port=port,
user=user,
password=password,
login_prompt=login_prompt,
exit_command=exit_command,
)
def read_tool_settings() -> ToolSettings:
tool_mode = parse_bool(os.environ.get("MISTLE_TOOL_MODE", ""))
tool_spec = os.environ.get("MISTLE_TOOL", "")
sideload_specs = parse_csv(os.environ.get("MISTLE_SIDELOAD_TOOL", ""))
autoplay = parse_bool(os.environ.get("MISTLE_AUTOPLAY", ""))
return ToolSettings(
tool_mode=tool_mode,
tool_spec=tool_spec,
sideload_specs=sideload_specs,
autoplay=autoplay,
)