feat: implement plugin architecture and application settings with Svelte UI

- Added plugin base and loader for backend extensibility
- Implemented application settings management with config persistence
- Created Svelte-based frontend with Dashboard and Settings pages
- Added API routes for plugins, tasks, and settings
- Updated documentation and specifications
- Improved project structure and developer tools
This commit is contained in:
2025-12-20 20:48:18 +03:00
parent ce703322c2
commit 2d8cae563f
98 changed files with 7894 additions and 5021 deletions

254
superset_tool/exceptions.py Normal file → Executable file
View File

@@ -1,128 +1,128 @@
# [DEF:superset_tool.exceptions:Module]
# @PURPOSE: Определяет иерархию пользовательских исключений для всего инструмента, обеспечивая единую точку обработки ошибок.
# @SEMANTICS: exception, error, hierarchy
# @LAYER: Infra
# [SECTION: IMPORTS]
from pathlib import Path
from typing import Optional, Dict, Any, Union
# [/SECTION]
# [DEF:SupersetToolError:Class]
# @PURPOSE: Базовый класс для всех ошибок, генерируемых инструментом.
# @RELATION: INHERITS_FROM -> Exception
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: context (Optional[Dict[str, Any]]) - Дополнительный контекст ошибки.
class SupersetToolError(Exception):
def __init__(self, message: str, context: Optional[Dict[str, Any]] = None):
self.context = context or {}
super().__init__(f"{message} | Context: {self.context}")
# [/DEF:SupersetToolError]
# [DEF:AuthenticationError:Class]
# @PURPOSE: Ошибки, связанные с аутентификацией или авторизацией.
# @RELATION: INHERITS_FROM -> SupersetToolError
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: context (Any) - Дополнительный контекст ошибки.
class AuthenticationError(SupersetToolError):
def __init__(self, message: str = "Authentication failed", **context: Any):
super().__init__(f"[AUTH_FAILURE] {message}", context={"type": "authentication", **context})
# [/DEF:AuthenticationError]
# [DEF:PermissionDeniedError:Class]
# @PURPOSE: Ошибка, возникающая при отказе в доступе к ресурсу.
# @RELATION: INHERITS_FROM -> AuthenticationError
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: required_permission (Optional[str]) - Требуемое разрешение.
# @PARAM: context (Any) - Дополнительный контекст ошибки.
class PermissionDeniedError(AuthenticationError):
def __init__(self, message: str = "Permission denied", required_permission: Optional[str] = None, **context: Any):
full_message = f"Permission denied: {required_permission}" if required_permission else message
super().__init__(full_message, context={"required_permission": required_permission, **context})
# [/DEF:PermissionDeniedError]
# [DEF:SupersetAPIError:Class]
# @PURPOSE: Общие ошибки при взаимодействии с Superset API.
# @RELATION: INHERITS_FROM -> SupersetToolError
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: context (Any) - Дополнительный контекст ошибки.
class SupersetAPIError(SupersetToolError):
def __init__(self, message: str = "Superset API error", **context: Any):
super().__init__(f"[API_FAILURE] {message}", context={"type": "api_call", **context})
# [/DEF:SupersetAPIError]
# [DEF:ExportError:Class]
# @PURPOSE: Ошибки, специфичные для операций экспорта.
# @RELATION: INHERITS_FROM -> SupersetAPIError
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: context (Any) - Дополнительный контекст ошибки.
class ExportError(SupersetAPIError):
def __init__(self, message: str = "Dashboard export failed", **context: Any):
super().__init__(f"[EXPORT_FAILURE] {message}", context={"subtype": "export", **context})
# [/DEF:ExportError]
# [DEF:DashboardNotFoundError:Class]
# @PURPOSE: Ошибка, когда запрошенный дашборд или ресурс не найден (404).
# @RELATION: INHERITS_FROM -> SupersetAPIError
# @PARAM: dashboard_id_or_slug (Union[int, str]) - ID или slug дашборда.
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: context (Any) - Дополнительный контекст ошибки.
class DashboardNotFoundError(SupersetAPIError):
def __init__(self, dashboard_id_or_slug: Union[int, str], message: str = "Dashboard not found", **context: Any):
super().__init__(f"[NOT_FOUND] Dashboard '{dashboard_id_or_slug}' {message}", context={"subtype": "not_found", "resource_id": dashboard_id_or_slug, **context})
# [/DEF:DashboardNotFoundError]
# [DEF:DatasetNotFoundError:Class]
# @PURPOSE: Ошибка, когда запрашиваемый набор данных не существует (404).
# @RELATION: INHERITS_FROM -> SupersetAPIError
# @PARAM: dataset_id_or_slug (Union[int, str]) - ID или slug набора данных.
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: context (Any) - Дополнительный контекст ошибки.
class DatasetNotFoundError(SupersetAPIError):
def __init__(self, dataset_id_or_slug: Union[int, str], message: str = "Dataset not found", **context: Any):
super().__init__(f"[NOT_FOUND] Dataset '{dataset_id_or_slug}' {message}", context={"subtype": "not_found", "resource_id": dataset_id_or_slug, **context})
# [/DEF:DatasetNotFoundError]
# [DEF:InvalidZipFormatError:Class]
# @PURPOSE: Ошибка, указывающая на некорректный формат или содержимое ZIP-архива.
# @RELATION: INHERITS_FROM -> SupersetToolError
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: file_path (Optional[Union[str, Path]]) - Путь к файлу.
# @PARAM: context (Any) - Дополнительный контекст ошибки.
class InvalidZipFormatError(SupersetToolError):
def __init__(self, message: str = "Invalid ZIP format or content", file_path: Optional[Union[str, Path]] = None, **context: Any):
super().__init__(f"[FILE_ERROR] {message}", context={"type": "file_validation", "file_path": str(file_path) if file_path else "N/A", **context})
# [/DEF:InvalidZipFormatError]
# [DEF:NetworkError:Class]
# @PURPOSE: Ошибки, связанные с сетевым соединением.
# @RELATION: INHERITS_FROM -> SupersetToolError
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: context (Any) - Дополнительный контекст ошибки.
class NetworkError(SupersetToolError):
def __init__(self, message: str = "Network connection failed", **context: Any):
super().__init__(f"[NETWORK_FAILURE] {message}", context={"type": "network", **context})
# [/DEF:NetworkError]
# [DEF:FileOperationError:Class]
# @PURPOSE: Общие ошибки файловых операций (I/O).
# @RELATION: INHERITS_FROM -> SupersetToolError
class FileOperationError(SupersetToolError):
pass
# [/DEF:FileOperationError]
# [DEF:InvalidFileStructureError:Class]
# @PURPOSE: Ошибка, указывающая на некорректную структуру файлов или директорий.
# @RELATION: INHERITS_FROM -> FileOperationError
class InvalidFileStructureError(FileOperationError):
pass
# [/DEF:InvalidFileStructureError]
# [DEF:ConfigurationError:Class]
# @PURPOSE: Ошибки, связанные с неверной конфигурацией инструмента.
# @RELATION: INHERITS_FROM -> SupersetToolError
class ConfigurationError(SupersetToolError):
pass
# [/DEF:ConfigurationError]
# [DEF:superset_tool.exceptions:Module]
# @PURPOSE: Определяет иерархию пользовательских исключений для всего инструмента, обеспечивая единую точку обработки ошибок.
# @SEMANTICS: exception, error, hierarchy
# @LAYER: Infra
# [SECTION: IMPORTS]
from pathlib import Path
from typing import Optional, Dict, Any, Union
# [/SECTION]
# [DEF:SupersetToolError:Class]
# @PURPOSE: Базовый класс для всех ошибок, генерируемых инструментом.
# @RELATION: INHERITS_FROM -> Exception
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: context (Optional[Dict[str, Any]]) - Дополнительный контекст ошибки.
class SupersetToolError(Exception):
def __init__(self, message: str, context: Optional[Dict[str, Any]] = None):
self.context = context or {}
super().__init__(f"{message} | Context: {self.context}")
# [/DEF:SupersetToolError]
# [DEF:AuthenticationError:Class]
# @PURPOSE: Ошибки, связанные с аутентификацией или авторизацией.
# @RELATION: INHERITS_FROM -> SupersetToolError
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: context (Any) - Дополнительный контекст ошибки.
class AuthenticationError(SupersetToolError):
def __init__(self, message: str = "Authentication failed", **context: Any):
super().__init__(f"[AUTH_FAILURE] {message}", context={"type": "authentication", **context})
# [/DEF:AuthenticationError]
# [DEF:PermissionDeniedError:Class]
# @PURPOSE: Ошибка, возникающая при отказе в доступе к ресурсу.
# @RELATION: INHERITS_FROM -> AuthenticationError
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: required_permission (Optional[str]) - Требуемое разрешение.
# @PARAM: context (Any) - Дополнительный контекст ошибки.
class PermissionDeniedError(AuthenticationError):
def __init__(self, message: str = "Permission denied", required_permission: Optional[str] = None, **context: Any):
full_message = f"Permission denied: {required_permission}" if required_permission else message
super().__init__(full_message, context={"required_permission": required_permission, **context})
# [/DEF:PermissionDeniedError]
# [DEF:SupersetAPIError:Class]
# @PURPOSE: Общие ошибки при взаимодействии с Superset API.
# @RELATION: INHERITS_FROM -> SupersetToolError
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: context (Any) - Дополнительный контекст ошибки.
class SupersetAPIError(SupersetToolError):
def __init__(self, message: str = "Superset API error", **context: Any):
super().__init__(f"[API_FAILURE] {message}", context={"type": "api_call", **context})
# [/DEF:SupersetAPIError]
# [DEF:ExportError:Class]
# @PURPOSE: Ошибки, специфичные для операций экспорта.
# @RELATION: INHERITS_FROM -> SupersetAPIError
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: context (Any) - Дополнительный контекст ошибки.
class ExportError(SupersetAPIError):
def __init__(self, message: str = "Dashboard export failed", **context: Any):
super().__init__(f"[EXPORT_FAILURE] {message}", context={"subtype": "export", **context})
# [/DEF:ExportError]
# [DEF:DashboardNotFoundError:Class]
# @PURPOSE: Ошибка, когда запрошенный дашборд или ресурс не найден (404).
# @RELATION: INHERITS_FROM -> SupersetAPIError
# @PARAM: dashboard_id_or_slug (Union[int, str]) - ID или slug дашборда.
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: context (Any) - Дополнительный контекст ошибки.
class DashboardNotFoundError(SupersetAPIError):
def __init__(self, dashboard_id_or_slug: Union[int, str], message: str = "Dashboard not found", **context: Any):
super().__init__(f"[NOT_FOUND] Dashboard '{dashboard_id_or_slug}' {message}", context={"subtype": "not_found", "resource_id": dashboard_id_or_slug, **context})
# [/DEF:DashboardNotFoundError]
# [DEF:DatasetNotFoundError:Class]
# @PURPOSE: Ошибка, когда запрашиваемый набор данных не существует (404).
# @RELATION: INHERITS_FROM -> SupersetAPIError
# @PARAM: dataset_id_or_slug (Union[int, str]) - ID или slug набора данных.
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: context (Any) - Дополнительный контекст ошибки.
class DatasetNotFoundError(SupersetAPIError):
def __init__(self, dataset_id_or_slug: Union[int, str], message: str = "Dataset not found", **context: Any):
super().__init__(f"[NOT_FOUND] Dataset '{dataset_id_or_slug}' {message}", context={"subtype": "not_found", "resource_id": dataset_id_or_slug, **context})
# [/DEF:DatasetNotFoundError]
# [DEF:InvalidZipFormatError:Class]
# @PURPOSE: Ошибка, указывающая на некорректный формат или содержимое ZIP-архива.
# @RELATION: INHERITS_FROM -> SupersetToolError
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: file_path (Optional[Union[str, Path]]) - Путь к файлу.
# @PARAM: context (Any) - Дополнительный контекст ошибки.
class InvalidZipFormatError(SupersetToolError):
def __init__(self, message: str = "Invalid ZIP format or content", file_path: Optional[Union[str, Path]] = None, **context: Any):
super().__init__(f"[FILE_ERROR] {message}", context={"type": "file_validation", "file_path": str(file_path) if file_path else "N/A", **context})
# [/DEF:InvalidZipFormatError]
# [DEF:NetworkError:Class]
# @PURPOSE: Ошибки, связанные с сетевым соединением.
# @RELATION: INHERITS_FROM -> SupersetToolError
# @PARAM: message (str) - Сообщение об ошибке.
# @PARAM: context (Any) - Дополнительный контекст ошибки.
class NetworkError(SupersetToolError):
def __init__(self, message: str = "Network connection failed", **context: Any):
super().__init__(f"[NETWORK_FAILURE] {message}", context={"type": "network", **context})
# [/DEF:NetworkError]
# [DEF:FileOperationError:Class]
# @PURPOSE: Общие ошибки файловых операций (I/O).
# @RELATION: INHERITS_FROM -> SupersetToolError
class FileOperationError(SupersetToolError):
pass
# [/DEF:FileOperationError]
# [DEF:InvalidFileStructureError:Class]
# @PURPOSE: Ошибка, указывающая на некорректную структуру файлов или директорий.
# @RELATION: INHERITS_FROM -> FileOperationError
class InvalidFileStructureError(FileOperationError):
pass
# [/DEF:InvalidFileStructureError]
# [DEF:ConfigurationError:Class]
# @PURPOSE: Ошибки, связанные с неверной конфигурацией инструмента.
# @RELATION: INHERITS_FROM -> SupersetToolError
class ConfigurationError(SupersetToolError):
pass
# [/DEF:ConfigurationError]
# [/DEF:superset_tool.exceptions]