Kansho/backend/env_loader.py
2026-08-25 13:57:23 +02:00

69 lines
2.2 KiB
Python

"""Load backend/.env into os.environ without overwriting a real process environment."""
from __future__ import annotations
import os
from pathlib import Path
ENV_PATH = Path(__file__).resolve().parent / ".env"
def load_env_file(path: Path | None = None) -> None:
target = path or ENV_PATH
if not target.is_file():
return
for raw in target.read_text(encoding="utf-8").splitlines():
line = raw.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, value = line.split("=", 1)
key = key.strip()
if not key or key in os.environ:
continue
value = value.strip()
if len(value) >= 2 and value[0] == value[-1] and value[0] in {"'", '"'}:
value = value[1:-1]
os.environ[key] = value
def runtime_env() -> str:
"""development/test may use remote plaintext detect. production must not."""
raw = (os.environ.get("KANSHO_ENV") or "").strip().lower()
if raw in {"production", "prod"}:
return "production"
if raw in {"test", "testing"}:
return "test"
if raw in {"development", "dev"}:
return "development"
return "development"
def allows_remote_plaintext_detect() -> bool:
return runtime_env() != "production"
def upsert_env_value(name: str, value: str, path: Path | None = None) -> None:
"""Write one key into backend/.env and the current process. Never log the value."""
target = path or ENV_PATH
name = name.strip()
if not name:
raise ValueError("empty env name")
lines: list[str] = []
if target.is_file():
lines = target.read_text(encoding="utf-8").splitlines()
found = False
updated: list[str] = []
prefix = f"{name}="
for line in lines:
stripped = line.strip()
if stripped.startswith(prefix) or stripped.startswith(f"{name} ="):
updated.append(f"{name}={value}")
found = True
else:
updated.append(line)
if not found:
if updated and updated[-1] != "":
updated.append("")
updated.append(f"{name}={value}")
target.write_text("\n".join(updated) + "\n", encoding="utf-8")
os.environ[name] = value