|
|
""" |
|
|
API Key Management for GEPA Optimizer |
|
|
""" |
|
|
|
|
|
import os |
|
|
from dotenv import load_dotenv |
|
|
from typing import Optional, Dict, List |
|
|
|
|
|
class APIKeyManager: |
|
|
"""Handles API keys securely without hardcoding""" |
|
|
|
|
|
def __init__(self): |
|
|
|
|
|
load_dotenv() |
|
|
self._keys: Dict[str, str] = {} |
|
|
self._load_from_env() |
|
|
|
|
|
def _load_from_env(self): |
|
|
"""Load API keys from environment variables""" |
|
|
env_mappings = { |
|
|
'openai': 'OPENAI_API_KEY', |
|
|
'anthropic': 'ANTHROPIC_API_KEY', |
|
|
'huggingface': 'HUGGINGFACE_API_KEY', |
|
|
'cohere': 'COHERE_API_KEY', |
|
|
'ai21': 'AI21_API_KEY', |
|
|
'together': 'TOGETHER_API_KEY', |
|
|
'replicate': 'REPLICATE_API_TOKEN', |
|
|
'groq': 'GROQ_API_KEY', |
|
|
'ollama': 'OLLAMA_API_KEY', |
|
|
'google': 'GEMINI_API_KEY', |
|
|
'gemini': 'GEMINI_API_KEY' |
|
|
} |
|
|
|
|
|
for provider, env_var in env_mappings.items(): |
|
|
key = os.getenv(env_var) |
|
|
if key: |
|
|
self._keys[provider] = key |
|
|
|
|
|
def get_api_key(self, provider: str) -> Optional[str]: |
|
|
"""Get API key for a specific provider""" |
|
|
return self._keys.get(provider.lower()) |
|
|
|
|
|
def set_api_key(self, provider: str, key: str): |
|
|
"""Set API key for a provider at runtime""" |
|
|
provider_lower = provider.lower() |
|
|
self._keys[provider_lower] = key |
|
|
|
|
|
|
|
|
if provider_lower == 'google': |
|
|
self._keys['gemini'] = key |
|
|
elif provider_lower == 'gemini': |
|
|
self._keys['google'] = key |
|
|
|
|
|
def has_key(self, provider: str) -> bool: |
|
|
"""Check if API key exists for provider""" |
|
|
return provider.lower() in self._keys |
|
|
|
|
|
def get_missing_keys(self, providers: List[str]) -> List[str]: |
|
|
"""Get list of providers missing API keys""" |
|
|
return [p for p in providers if not self.has_key(p)] |
|
|
|
|
|
def validate_keys(self, providers: List[str]) -> Dict[str, bool]: |
|
|
"""Validate API keys for multiple providers""" |
|
|
return {provider: self.has_key(provider) for provider in providers} |
|
|
|
|
|
|
|
|
def set_openai_key(self, key: str): |
|
|
"""Set OpenAI API key at runtime""" |
|
|
self.set_api_key('openai', key) |
|
|
|
|
|
def set_anthropic_key(self, key: str): |
|
|
"""Set Anthropic API key at runtime""" |
|
|
self.set_api_key('anthropic', key) |
|
|
|
|
|
def set_google_key(self, key: str): |
|
|
"""Set Google API key at runtime""" |
|
|
self.set_api_key('google', key) |
|
|
|
|
|
def set_gemini_key(self, key: str): |
|
|
"""Set Gemini API key at runtime (alias for Google)""" |
|
|
self.set_api_key('google', key) |
|
|
|
|
|
def get_openai_key(self) -> str: |
|
|
"""Get OpenAI key or raise error if missing""" |
|
|
key = self.get_api_key('openai') |
|
|
if not key: |
|
|
raise RuntimeError( |
|
|
"OpenAI API key missing. Set via:\n" |
|
|
"1. Environment variable: OPENAI_API_KEY=your_key\n" |
|
|
"2. .env file: OPENAI_API_KEY=your_key\n" |
|
|
"3. Code: api_manager.set_api_key('openai', 'your_key')" |
|
|
) |
|
|
return key |
|
|
|
|
|
def get_anthropic_key(self) -> Optional[str]: |
|
|
"""Get Anthropic key (optional)""" |
|
|
return self.get_api_key('anthropic') |
|
|
|
|
|
def get_google_key(self) -> Optional[str]: |
|
|
"""Get Google key (optional)""" |
|
|
return self.get_api_key('google') |
|
|
|
|
|
def get_gemini_key(self) -> Optional[str]: |
|
|
"""Get Gemini key (alias for Google)""" |
|
|
return self.get_api_key('google') |
|
|
|
|
|
def has_required_keys(self) -> bool: |
|
|
"""Check if required keys are available""" |
|
|
return bool(self.get_api_key('openai')) |
|
|
|