# [DEF:superset_tool.utils.init_clients:Module] # # @SEMANTICS: utility, factory, client, initialization, configuration # @PURPOSE: Централизованно инициализирует клиенты Superset для различных окружений (DEV, PROD, SBX, PREPROD), используя `keyring` для безопасного доступа к паролям. # @LAYER: Infra # @RELATION: DEPENDS_ON -> superset_tool.models # @RELATION: DEPENDS_ON -> superset_tool.client # @RELATION: DEPENDS_ON -> keyring # @PUBLIC_API: setup_clients # [SECTION: IMPORTS] import keyring import os from typing import Dict, List, Optional, Any from superset_tool.models import SupersetConfig from superset_tool.client import SupersetClient from superset_tool.utils.logger import SupersetLogger # [/SECTION] # [DEF:setup_clients:Function] # @PURPOSE: Инициализирует и возвращает словарь клиентов `SupersetClient`. # @PRE: `logger` должен быть валидным экземпляром `SupersetLogger`. # @POST: Возвращает словарь с инициализированными клиентами. # @THROW: Exception - При любых других ошибках инициализации. # @RELATION: CREATES_INSTANCE_OF -> SupersetConfig # @RELATION: CREATES_INSTANCE_OF -> SupersetClient # @PARAM: logger (SupersetLogger) - Экземпляр логгера для записи процесса. # @PARAM: custom_envs (List[Dict[str, Any]]) - Список пользовательских настроек окружений. # @RETURN: Dict[str, SupersetClient] - Словарь, где ключ - имя окружения, значение - `SupersetClient`. def setup_clients(logger: SupersetLogger, custom_envs: Optional[List[Any]] = None) -> Dict[str, SupersetClient]: logger.info("[setup_clients][Enter] Starting Superset clients initialization.") clients = {} try: # Try to load from ConfigManager if available try: from backend.src.dependencies import get_config_manager config_manager = get_config_manager() envs = config_manager.get_environments() if envs: logger.info("[setup_clients][Action] Loading environments from ConfigManager") for env in envs: logger.debug("[setup_clients][State] Creating config for environment: %s", env.name) config = SupersetConfig( env=env.name, base_url=env.url, auth={"provider": "db", "username": env.username, "password": env.password, "refresh": "true"}, verify_ssl=False, timeout=30, logger=logger ) clients[env.name] = SupersetClient(config, logger) return clients except (ImportError, Exception) as e: logger.debug(f"[setup_clients][State] ConfigManager not available or failed: {e}") if custom_envs: for env in custom_envs: # Handle both dict and object (like Pydantic model) env_name = str(getattr(env, 'name', env.get('name') if isinstance(env, dict) else "unknown")) base_url = str(getattr(env, 'url', env.get('url') if isinstance(env, dict) else "")) username = str(getattr(env, 'username', env.get('username') if isinstance(env, dict) else "")) password = str(getattr(env, 'password', env.get('password') if isinstance(env, dict) else "")) logger.debug("[setup_clients][State] Creating config for custom environment: %s", env_name) config = SupersetConfig( env=env_name, base_url=base_url, auth={"provider": "db", "username": username, "password": password, "refresh": "true"}, verify_ssl=False, timeout=30, logger=logger ) clients[env_name] = SupersetClient(config, logger) else: # Fallback to hardcoded environments with keyring environments = { "dev": "https://devta.bi.dwh.rusal.com/api/v1", "prod": "https://prodta.bi.dwh.rusal.com/api/v1", "sbx": "https://sandboxta.bi.dwh.rusal.com/api/v1", "preprod": "https://preprodta.bi.dwh.rusal.com/api/v1", "uatta": "https://uatta.bi.dwh.rusal.com/api/v1", "dev5":"https://dev.bi.dwh.rusal.com/api/v1" } for env_name, base_url in environments.items(): logger.debug("[setup_clients][State] Creating config for environment: %s", env_name.upper()) password = keyring.get_password("system", f"{env_name} migrate") if not password: logger.warning(f"Пароль для '{env_name} migrate' не найден в keyring. Пропускаем.") continue config = SupersetConfig( env=env_name, base_url=base_url, auth={"provider": "db", "username": "migrate_user", "password": password, "refresh": "true"}, verify_ssl=False, timeout=30, logger=logger ) clients[env_name] = SupersetClient(config, logger) logger.info("[setup_clients][Exit] All clients (%s) initialized successfully.", ', '.join(clients.keys())) return clients except Exception as e: logger.critical("[setup_clients][Failure] Critical error during client initialization: %s", e, exc_info=True) raise # [/DEF:setup_clients] # [/DEF:superset_tool.utils.init_clients]