diff --git a/backend/delete_running_tasks.py b/backend/delete_running_tasks.py new file mode 100644 index 0000000..927bc7a --- /dev/null +++ b/backend/delete_running_tasks.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +"""Script to delete tasks with RUNNING status from the database.""" + +from sqlalchemy.orm import Session +from src.core.database import TasksSessionLocal +from src.models.task import TaskRecord + +def delete_running_tasks(): + """Delete all tasks with RUNNING status from the database.""" + session: Session = TasksSessionLocal() + try: + # Find all task records with RUNNING status + running_tasks = session.query(TaskRecord).filter(TaskRecord.status == "RUNNING").all() + + if not running_tasks: + print("No RUNNING tasks found.") + return + + print(f"Found {len(running_tasks)} RUNNING tasks:") + for task in running_tasks: + print(f"- Task ID: {task.id}, Type: {task.type}") + + # Delete the found tasks + session.query(TaskRecord).filter(TaskRecord.status == "RUNNING").delete(synchronize_session=False) + session.commit() + + print(f"Successfully deleted {len(running_tasks)} RUNNING tasks.") + except Exception as e: + session.rollback() + print(f"Error deleting tasks: {e}") + finally: + session.close() + +if __name__ == "__main__": + delete_running_tasks() diff --git a/backend/src/core/config_manager.py b/backend/src/core/config_manager.py index 7a578f7..741aeb6 100755 --- a/backend/src/core/config_manager.py +++ b/backend/src/core/config_manager.py @@ -186,6 +186,20 @@ class ConfigManager: return len(self.config.environments) > 0 # [/DEF:has_environments:Function] + # [DEF:get_environment:Function] + # @PURPOSE: Returns a single environment by ID. + # @PRE: self.config is set and isinstance(env_id, str) and len(env_id) > 0. + # @POST: Returns Environment object if found, None otherwise. + # @PARAM: env_id (str) - The ID of the environment to retrieve. + # @RETURN: Optional[Environment] - The environment with the given ID, or None. + def get_environment(self, env_id: str) -> Optional[Environment]: + with belief_scope("get_environment"): + for env in self.config.environments: + if env.id == env_id: + return env + return None + # [/DEF:get_environment:Function] + # [DEF:add_environment:Function] # @PURPOSE: Adds a new environment to the configuration. # @PRE: isinstance(env, Environment) diff --git a/backend/src/core/superset_client.py b/backend/src/core/superset_client.py index ebf15dd..a960a7d 100644 --- a/backend/src/core/superset_client.py +++ b/backend/src/core/superset_client.py @@ -9,7 +9,7 @@ # [SECTION: IMPORTS] from typing import List, Dict, Optional, Tuple -from backend.src.core.logger import belief_scope +from .logger import belief_scope from superset_tool.client import SupersetClient as BaseSupersetClient from superset_tool.models import SupersetConfig # [/SECTION] @@ -17,6 +17,14 @@ from superset_tool.models import SupersetConfig # [DEF:SupersetClient:Class] # @PURPOSE: Extended SupersetClient for migration-specific operations. class SupersetClient(BaseSupersetClient): + # [DEF:authenticate:Function] + # @PURPOSE: Authenticates the client using the configured credentials. + # @PRE: self.network must be initialized with valid auth configuration. + # @POST: Client is authenticated and tokens are stored. + # @RETURN: Dict[str, str] - Authentication tokens. + def authenticate(self): + with belief_scope("SupersetClient.authenticate"): + return self.network.authenticate() # [DEF:get_databases_summary:Function] # @PURPOSE: Fetch a summary of databases including uuid, name, and engine. diff --git a/backend/src/plugins/debug.py b/backend/src/plugins/debug.py index 5394f2f..29129b3 100644 --- a/backend/src/plugins/debug.py +++ b/backend/src/plugins/debug.py @@ -145,7 +145,19 @@ class DebugPlugin(PluginBase): if not env_config: raise ValueError(f"Environment '{name}' not found.") - client = SupersetClient(env_config) + # Map Environment model to SupersetConfig + from superset_tool.models import SupersetConfig + superset_config = SupersetConfig( + env=env_config.name, + base_url=env_config.url, + auth={ + "provider": "db", # Defaulting to db provider + "username": env_config.username, + "password": env_config.password, + "refresh": "false" + } + ) + client = SupersetClient(superset_config) client.authenticate() count, dbs = client.get_databases() results[name] = { @@ -176,7 +188,19 @@ class DebugPlugin(PluginBase): if not env_config: raise ValueError(f"Environment '{env_name}' not found.") - client = SupersetClient(env_config) + # Map Environment model to SupersetConfig + from superset_tool.models import SupersetConfig + superset_config = SupersetConfig( + env=env_config.name, + base_url=env_config.url, + auth={ + "provider": "db", # Defaulting to db provider + "username": env_config.username, + "password": env_config.password, + "refresh": "false" + } + ) + client = SupersetClient(superset_config) client.authenticate() dataset_response = client.get_dataset(dataset_id) diff --git a/backend/src/plugins/mapper.py b/backend/src/plugins/mapper.py index 6103d1e..c8dc7a3 100644 --- a/backend/src/plugins/mapper.py +++ b/backend/src/plugins/mapper.py @@ -137,13 +137,25 @@ class MapperPlugin(PluginBase): # Get config and initialize client from ..dependencies import get_config_manager + from superset_tool.models import SupersetConfig config_manager = get_config_manager() env_config = config_manager.get_environment(env_name) if not env_config: logger.error(f"[MapperPlugin.execute][State] Environment '{env_name}' not found.") raise ValueError(f"Environment '{env_name}' not found in configuration.") - client = SupersetClient(env_config) + # Map Environment model to SupersetConfig + superset_config = SupersetConfig( + env=env_config.name, + base_url=env_config.url, + auth={ + "provider": "db", # Defaulting to db provider + "username": env_config.username, + "password": env_config.password, + "refresh": "false" + } + ) + client = SupersetClient(superset_config) client.authenticate() postgres_config = None diff --git a/backend/src/plugins/search.py b/backend/src/plugins/search.py index 9a39949..3f5b768 100644 --- a/backend/src/plugins/search.py +++ b/backend/src/plugins/search.py @@ -106,13 +106,25 @@ class SearchPlugin(PluginBase): # Get config and initialize client from ..dependencies import get_config_manager + from superset_tool.models import SupersetConfig config_manager = get_config_manager() env_config = config_manager.get_environment(env_name) if not env_config: logger.error(f"[SearchPlugin.execute][State] Environment '{env_name}' not found.") raise ValueError(f"Environment '{env_name}' not found in configuration.") - client = SupersetClient(env_config) + # Map Environment model to SupersetConfig + superset_config = SupersetConfig( + env=env_config.name, + base_url=env_config.url, + auth={ + "provider": "db", # Defaulting to db provider + "username": env_config.username, + "password": env_config.password, + "refresh": "false" + } + ) + client = SupersetClient(superset_config) client.authenticate() logger.info(f"[SearchPlugin.execute][Action] Searching for pattern: '{search_query}' in environment: {env_name}") diff --git a/backend/tasks.db b/backend/tasks.db index 0287710..568cc61 100644 Binary files a/backend/tasks.db and b/backend/tasks.db differ diff --git a/backend/test_fix.py b/backend/test_fix.py new file mode 100644 index 0000000..7923333 --- /dev/null +++ b/backend/test_fix.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +"""Test script to verify the fixes for SupersetClient initialization.""" + +import sys +sys.path.insert(0, '.') + +from src.core.config_manager import ConfigManager +from src.core.config_models import Environment +from src.plugins.search import SearchPlugin +from src.plugins.mapper import MapperPlugin +from src.plugins.debug import DebugPlugin + +def test_config_manager(): + """Test ConfigManager methods.""" + print("Testing ConfigManager...") + try: + config_manager = ConfigManager() + print(f" ConfigManager initialized") + + # Test get_environment method + if hasattr(config_manager, 'get_environment'): + print(f" get_environment method exists") + + # Add a test environment if none exists + if not config_manager.has_environments(): + test_env = Environment( + id="test-env", + name="Test Environment", + url="http://localhost:8088", + username="admin", + password="admin" + ) + config_manager.add_environment(test_env) + print(f" Added test environment: {test_env.name}") + + # Test retrieving environment + envs = config_manager.get_environments() + if envs: + test_env_id = envs[0].id + env_config = config_manager.get_environment(test_env_id) + print(f" Successfully retrieved environment: {env_config.name}") + return True + else: + print(f" No environments available (add one in settings)") + return False + + except Exception as e: + print(f" Error: {e}") + return False + +def test_plugins(): + """Test plugin initialization.""" + print("\nTesting plugins...") + + plugins = [ + ("Search Plugin", SearchPlugin()), + ("Mapper Plugin", MapperPlugin()), + ("Debug Plugin", DebugPlugin()) + ] + + all_ok = True + + for name, plugin in plugins: + print(f"\nTesting {name}...") + try: + plugin_id = plugin.id + plugin_name = plugin.name + plugin_version = plugin.version + schema = plugin.get_schema() + + print(f" ✓ ID: {plugin_id}") + print(f" ✓ Name: {plugin_name}") + print(f" ✓ Version: {plugin_version}") + print(f" ✓ Schema: {schema}") + + except Exception as e: + print(f" ✗ Error: {e}") + all_ok = False + + return all_ok + +def main(): + """Main test function.""" + print("=" * 50) + print("Superset Tools Fix Verification") + print("=" * 50) + + config_ok = test_config_manager() + plugins_ok = test_plugins() + + print("\n" + "=" * 50) + if config_ok and plugins_ok: + print("✅ All fixes verified successfully!") + else: + print("❌ Some tests failed") + sys.exit(1) + +if __name__ == "__main__": + main() diff --git a/frontend/src/components/Navbar.svelte b/frontend/src/components/Navbar.svelte index d2d9ba7..98c90bd 100644 --- a/frontend/src/components/Navbar.svelte +++ b/frontend/src/components/Navbar.svelte @@ -39,7 +39,7 @@ -