import os from dotenv import load_dotenv class ConfigManager: """Safely manages multi-line .env files without corrupting other content.""" @staticmethod def get_root_env_path(): # backend/config_manager.py -> backend/ -> / base_dir = os.path.dirname(os.path.abspath(__file__)) project_root = os.path.dirname(base_dir) return os.path.join(project_root, "inventory.env") @staticmethod def update_keys(updates: dict): """ Updates specific keys in inventory.env. Preserves comments and order where possible. Appends new keys at the end if not found. """ env_path = ConfigManager.get_root_env_path() if not os.path.exists(env_path): # Create a basic file if it doesn't exist (unlikely in this project) with open(env_path, 'w', encoding='utf-8') as f: f.write("# TFM aInventory — Generated Configuration\n") with open(env_path, 'r', encoding='utf-8') as f: lines = f.readlines() new_lines = [] keys_to_process = set(updates.keys()) processed_keys = set() for line in lines: trimmed = line.strip() # Skip empty lines or comments when matching if not trimmed or trimmed.startswith('#'): new_lines.append(line) continue # Check if this line is a key assignment we want to update found_match = False for key in keys_to_process: if trimmed.startswith(f"{key}="): new_lines.append(f"{key}={updates[key]}\n") processed_keys.add(key) found_match = True break if not found_match: new_lines.append(line) # Append keys that weren't found in the file missing_keys = keys_to_process - processed_keys if missing_keys: if new_lines and not new_lines[-1].endswith('\n'): new_lines.append('\n') if new_lines and not new_lines[-1].strip() == '': new_lines.append('\n') new_lines.append("# --- Automatically Added Keys ---\n") for key in missing_keys: new_lines.append(f"{key}={updates[key]}\n") with open(env_path, 'w', encoding='utf-8') as f: f.writelines(new_lines) # Force reload environment variables for the current process load_dotenv(env_path, override=True) return True @staticmethod def get_masked_key(key_name: str): """Returns a masked version of the environment variable.""" val = os.environ.get(key_name) if not val: return None # Determine prefix based on key type prefix = "" if key_name == "GEMINI_API_KEY": prefix = "G-" elif key_name == "CLAUDE_API_KEY": prefix = "sk-" if len(val) <= 8: return f"{prefix}****" return f"{prefix}****{val[-4:]}"