setup_validator.py
1 """Pre-onboarding validation utilities. 2 3 Lightweight checks the AI agent runs before and during onboarding to verify 4 prerequisites and environment configuration. No heavy imports (config.settings, 5 integrations) — those are validated via existing live tests. 6 """ 7 8 __all__ = ["check_prerequisites", "validate_env"] 9 10 from pathlib import Path 11 12 from dotenv import dotenv_values 13 14 _PROJECT_ROOT = Path(__file__).resolve().parents[1] 15 16 # All env vars the project recognises, grouped by purpose. 17 _KNOWN_ENV_VARS: dict[str, list[str]] = { 18 "llm_providers": [ 19 "ANTHROPIC_API_KEY", 20 "OPENAI_API_KEY", 21 "GEMINI_API_KEY", 22 "XAI_API_KEY", 23 "DEEPSEEK_API_KEY", 24 "MISTRAL_API_KEY", 25 ], 26 "integrations": [ 27 "BRIGHTDATA_TOKEN", 28 "NOTION_TOKEN", 29 "NOTION_JOBS_DATABASE_ID", 30 ], 31 } 32 33 34 def check_prerequisites() -> list[str]: 35 """Check that minimal files exist before onboarding can proceed. 36 37 Does NOT check for persona or prompt files — those are created during 38 onboarding. Does NOT import ``config.settings``. 39 40 Returns: 41 List of human-readable issues. Empty list means all checks pass. 42 """ 43 issues: list[str] = [] 44 45 # .env file. 46 env_path = _PROJECT_ROOT / ".env" 47 if not env_path.exists(): 48 issues.append(f".env file not found at {env_path}") 49 50 # config.toml file. 51 config_path = _PROJECT_ROOT / "config.toml" 52 if not config_path.exists(): 53 issues.append(f"config.toml not found at {config_path}") 54 55 return issues 56 57 58 def validate_env() -> dict[str, bool]: 59 """Read ``.env`` and report which known env vars are set. 60 61 Only reads the ``.env`` file — vars exported in the shell are intentionally 62 not checked. The onboarding guide directs users to put keys in ``.env``. 63 64 A var is considered *set* when its value is a non-empty string after 65 stripping whitespace. Placeholder values (e.g. ``your_key_here``) are 66 treated as set — the live tests catch invalid keys. 67 68 Returns: 69 Mapping of ``{var_name: is_set}`` for every known env var. 70 """ 71 env_path = _PROJECT_ROOT / ".env" 72 values = dotenv_values(env_path) if env_path.exists() else {} 73 74 result: dict[str, bool] = {} 75 for var_names in _KNOWN_ENV_VARS.values(): 76 for var in var_names: 77 raw = values.get(var) 78 result[var] = bool(raw and raw.strip()) 79 return result