fix(config): Ensure API keys are loaded by orchestrator

- Reverts docker-compose.yml to use volume mount for gemini_api_key.txt, due to format constraints.
- Restores and refines Config.load_api_keys() in config.py.
- **Crucially, calls Config.load_api_keys() at the start of gtm_architect_orchestrator.py to ensure keys are loaded.**
- Adjusts _get_gemini_api_key in helpers.py to prioritize keys from Config.API_KEYS.
- This definitively addresses the 'API Key missing' error by guaranteeing key initialization.
This commit is contained in:
2026-01-03 09:33:33 +00:00
parent b35a53b755
commit ca1309adff
4 changed files with 44 additions and 18 deletions

View File

@@ -482,9 +482,30 @@ class Config:
"NetCologne"
]
# --- API Schlüssel Speicherung (werden jetzt via Env Var geladen) ---
# --- API Schlüssel Speicherung (werden in main() geladen) ---
API_KEYS = {}
@classmethod
def load_api_keys(cls):
"""Laedt API-Schluessel aus den definierten Dateien."""
logger = logging.getLogger(__name__)
logger.info("Lade API-Schluessel...")
cls.API_KEYS['openai'] = cls._load_key_from_file(API_KEY_FILE)
cls.API_KEYS['serpapi'] = cls._load_key_from_file(SERP_API_KEY_FILE)
cls.API_KEYS['genderize'] = cls._load_key_from_file(GENDERIZE_API_KEY_FILE)
if cls.API_KEYS.get('openai'):
# Hier nehmen wir an, dass 'openai' für Gemini verwendet wird (Legacy)
# Falls in helpers.py direkt auf 'gemini' zugegriffen wird, müsste das hier auch gesetzt werden.
logger.info("Gemini API Key (via 'openai' slot) erfolgreich geladen.")
else:
logger.warning("Gemini API Key konnte nicht geladen werden. KI-Funktionen sind deaktiviert.")
if not cls.API_KEYS.get('serpapi'):
logger.warning("SerpAPI Key konnte nicht geladen werden. Suchfunktionen sind deaktiviert.")
if not cls.API_KEYS.get('genderize'):
logger.warning("Genderize API Key konnte nicht geladen werden. Geschlechtserkennung ist eingeschraenkt.")
@staticmethod
def _load_key_from_file(filepath):
"""Hilfsfunktion zum Laden eines Schluessels aus einer Datei."""

View File

@@ -101,8 +101,9 @@ services:
- ./gtm_db_manager.py:/app/gtm_db_manager.py
- ./gtm_projects.db:/app/gtm_projects.db
- ./Log_from_docker:/app/Log_from_docker
environment:
# Mount API keys
- ./gemini_api_key.txt:/app/gemini_api_key.txt
- ./serpapikey.txt:/app/serpapikey.txt
environment:
- PYTHONUNBUFFERED=1
- DB_PATH=/app/gtm_projects.db
env_file:
- ./gemini_api_key.txt
- DB_PATH=/app/gtm_projects.db

View File

@@ -15,6 +15,7 @@ import gtm_db_manager as db_manager
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from helpers import call_gemini_flash, scrape_website_details
from config import Config, BASE_DIR # Import Config and BASE_DIR
LOG_DIR = "Log_from_docker"
if not os.path.exists(LOG_DIR):
@@ -33,6 +34,10 @@ logging.basicConfig(
]
)
logging.info(f"GTM Architect Orchestrator v{{ORCHESTRATOR_VERSION}} ({{run_timestamp}}) starting...")
# !!! CRITICAL FIX: Load API keys at the very beginning !!!
# This ensures Config.API_KEYS is populated before any AI functions are called.
Config.load_api_keys()
def log_and_save(project_id, step_name, data_type, content):
logging.info(f"Project {project_id} - Step: {step_name} - Type: {data_type}")
filename = f"{run_timestamp}_{step_name}_{data_type}.txt"

View File

@@ -294,31 +294,30 @@ def get_email_address(firstname, lastname, website):
def _get_gemini_api_key():
"""
Retrieves Gemini API Key, prioritizing environment variables as the most robust method.
Retrieves Gemini API Key, prioritizing Config.API_KEYS after it has been loaded.
"""
logger = logging.getLogger(__name__)
logging.info("Attempting to retrieve Gemini API Key...")
# Primary Method: Environment Variable (most robust for Docker)
# Primary Method: From Config.API_KEYS (expected to be loaded by orchestrator)
api_key = Config.API_KEYS.get('gemini') or Config.API_KEYS.get('openai') # Check both slots
if api_key:
logging.info("Successfully loaded API key from Config.API_KEYS.")
return api_key
# Fallback 1: Environment Variable GEMINI_API_KEY
api_key = os.environ.get("GEMINI_API_KEY")
if api_key:
logging.info("Successfully loaded API key from GEMINI_API_KEY environment variable.")
logging.warning("Loaded API key from GEMINI_API_KEY environment variable (Config.API_KEYS was empty).")
return api_key
# Fallback 1: Legacy Environment Variable
# Fallback 2: Legacy Environment Variable OPENAI_API_KEY
api_key = os.environ.get("OPENAI_API_KEY")
if api_key:
logging.warning("Loaded API key from legacy OPENAI_API_KEY environment variable.")
return api_key
# Fallback 2: File-based (less reliable with volume mounts)
logging.warning("Could not find API key in environment variables. Falling back to file-based method.")
api_key = Config.API_KEYS.get('openai') # Legacy slot in config
if api_key:
logging.info("Successfully loaded API key from config file.")
logging.warning("Loaded API key from legacy OPENAI_API_KEY environment variable (Config.API_KEYS was empty).")
return api_key
logger.error("CRITICAL: No API Key found in environment variables or config file.")
logger.error("CRITICAL: No API Key found in Config.API_KEYS or environment variables.")
raise ValueError("API Key missing.")
@retry_on_failure