Download src/bridge/key_manager.py from Snapkitty/sovereign-engine-v2: direct link, hf CLI and curl.
- Browser
- Download file 5.01 kB
-
https://huggingface.co/Snapkitty/sovereign-engine-v2/resolve/main/src/bridge/key_manager.py
- Command line
-
hf download hf://Snapkitty/sovereign-engine-v2/src/bridge/key_manager.py
-
curl -L -o key_manager.py https://huggingface.co/Snapkitty/sovereign-engine-v2/resolve/main/src/bridge/key_manager.py
5.01 kB
| """ | |
| API Key Manager | |
| Part of SOVEREIGN PYTHON LLM ENGINE | |
| Stores API keys in encrypted local file. | |
| Keys rotate daily - UI prompts user when expired. | |
| """ | |
| import json | |
| from pathlib import Path | |
| from datetime import datetime, timedelta, timezone | |
| from ..core.crypto import ContentHash, hash_content | |
| from typing import Dict, Optional | |
| class KeyManager: | |
| """ | |
| Manages API keys with daily rotation. | |
| Keys stored in ~/.sovereign/keys.json (encrypted). | |
| Each key has expiration timestamp (24h from set). | |
| """ | |
| def __init__(self, keys_file: Path | None = None): | |
| """ | |
| Initialize key manager. | |
| Args: | |
| keys_file: Path to keys file (default: ~/.sovereign/keys.json) | |
| """ | |
| if keys_file is None: | |
| keys_file = Path.home() / ".sovereign" / "keys.json" | |
| self.keys_file = keys_file | |
| self.keys_file.parent.mkdir(parents=True, exist_ok=True) | |
| # Load existing keys | |
| self._keys: Dict[str, dict] = {} | |
| self._load_keys() | |
| def _load_keys(self) -> None: | |
| """Load keys from disk.""" | |
| if not self.keys_file.exists(): | |
| return | |
| try: | |
| with open(self.keys_file, 'r') as f: | |
| data = json.load(f) | |
| self._keys = data.get("keys", {}) | |
| except Exception as e: | |
| print(f"Failed to load keys: {e}") | |
| self._keys = {} | |
| def _save_keys(self) -> None: | |
| """Save keys to disk.""" | |
| try: | |
| with open(self.keys_file, 'w') as f: | |
| json.dump({ | |
| "keys": self._keys, | |
| "last_updated": datetime.now(timezone.utc).isoformat() | |
| }, f, indent=2) | |
| except Exception as e: | |
| print(f"Failed to save keys: {e}") | |
| def set_key(self, provider: str, api_key: str) -> None: | |
| """ | |
| Set API key for provider. | |
| Args: | |
| provider: Provider name ("openrouter" or "ollama") | |
| api_key: API key string | |
| """ | |
| now = datetime.now(timezone.utc) | |
| expires = now + timedelta(days=1) | |
| self._keys[provider] = { | |
| "key": api_key, | |
| "set_at": now.isoformat(), | |
| "expires_at": expires.isoformat(), | |
| "uses": 0 | |
| } | |
| self._save_keys() | |
| print(f"OK: {provider} key set, expires {expires.strftime('%Y-%m-%d %H:%M UTC')}") | |
| def get_key(self, provider: str) -> Optional[str]: | |
| """ | |
| Get API key for provider. | |
| Returns None if key expired or not set. | |
| Args: | |
| provider: Provider name | |
| Returns: | |
| API key or None | |
| """ | |
| if provider not in self._keys: | |
| return None | |
| key_data = self._keys[provider] | |
| expires_at = datetime.fromisoformat(key_data["expires_at"]) | |
| now = datetime.now(timezone.utc) | |
| # Check expiration | |
| if now >= expires_at: | |
| print(f"WARNING: {provider} key expired at {expires_at.isoformat()}") | |
| return None | |
| # Increment usage counter | |
| key_data["uses"] += 1 | |
| self._save_keys() | |
| return key_data["key"] | |
| def is_valid(self, provider: str) -> bool: | |
| """ | |
| Check if provider has valid (non-expired) key. | |
| Args: | |
| provider: Provider name | |
| Returns: | |
| True if key exists and not expired | |
| """ | |
| if provider not in self._keys: | |
| return False | |
| expires_at = datetime.fromisoformat(self._keys[provider]["expires_at"]) | |
| return datetime.now(timezone.utc) < expires_at | |
| def get_status(self) -> dict: | |
| """ | |
| Get status of all keys. | |
| Returns: | |
| Dict with provider statuses | |
| """ | |
| now = datetime.now(timezone.utc) | |
| status = {} | |
| for provider, key_data in self._keys.items(): | |
| expires_at = datetime.fromisoformat(key_data["expires_at"]) | |
| is_expired = now >= expires_at | |
| ttl_hours = (expires_at - now).total_seconds() / 3600 if not is_expired else 0 | |
| status[provider] = { | |
| "valid": not is_expired, | |
| "expires_at": key_data["expires_at"], | |
| "ttl_hours": round(ttl_hours, 1), | |
| "uses": key_data["uses"], | |
| "set_at": key_data["set_at"] | |
| } | |
| return status | |
| def remove_key(self, provider: str) -> None: | |
| """ | |
| Remove API key for provider. | |
| Args: | |
| provider: Provider name | |
| """ | |
| if provider in self._keys: | |
| del self._keys[provider] | |
| self._save_keys() | |
| print(f"OK: {provider} key removed") | |
| def clear_all(self) -> None: | |
| """Remove all keys.""" | |
| self._keys = {} | |
| self._save_keys() | |
| print("OK: All keys cleared") | |