""" DeepCoin .env 로드 (프로젝트 루트 기준). config·HTS·스크립트 진입 전에 한 번 호출하면 cwd와 무관하게 동일한 설정을 사용합니다. """ from __future__ import annotations import os from pathlib import Path from deepcoin.paths import PROJECT_ROOT _ENV_LOADED = False _ENV_LOADER = "none" ENV_FILE = PROJECT_ROOT / ".env" def _load_env_fallback(*, override: bool) -> None: """ python-dotenv 미설치 시 .env 를 직접 파싱해 os.environ 에 반영합니다. Args: override: True면 기존 키를 .env 값으로 덮어씀. """ if not ENV_FILE.is_file(): return for line in ENV_FILE.read_text(encoding="utf-8").splitlines(): line = line.strip() if not line or line.startswith("#"): continue if line.startswith("export "): line = line[7:].strip() if "=" not in line: continue key, _, value = line.partition("=") key = key.strip() value = value.strip().strip('"').strip("'") if not key: continue if not override and key in os.environ: continue os.environ[key] = value def load_project_env(*, override: bool = False) -> bool: """ PROJECT_ROOT/.env 를 로드합니다 (python-dotenv 우선, 없으면 fallback). Args: override: True면 기존 OS 환경 변수를 .env 값으로 덮어씀. Returns: .env 파일이 존재해 로드했으면 True, 없으면 False. """ global _ENV_LOADED, _ENV_LOADER if _ENV_LOADED and not override: return ENV_FILE.is_file() if not ENV_FILE.is_file(): _ENV_LOADED = True _ENV_LOADER = "missing" return False try: from dotenv import load_dotenv load_dotenv(ENV_FILE, override=override) _ENV_LOADER = "dotenv" except ImportError: _load_env_fallback(override=override) _ENV_LOADER = "fallback" _ENV_LOADED = True return True def env_status() -> dict[str, str | bool]: """디버그용 .env 상태.""" return { "project_root": str(PROJECT_ROOT), "env_file": str(ENV_FILE), "env_exists": ENV_FILE.is_file(), "loaded": _ENV_LOADED, "loader": _ENV_LOADER, "live_trading_enabled": os.getenv("LIVE_TRADING_ENABLED", ""), }