py-data-engine 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data_engine/__init__.py +37 -0
- data_engine/application/__init__.py +39 -0
- data_engine/application/actions.py +42 -0
- data_engine/application/catalog.py +151 -0
- data_engine/application/control.py +213 -0
- data_engine/application/details.py +73 -0
- data_engine/application/runtime.py +449 -0
- data_engine/application/workspace.py +62 -0
- data_engine/authoring/__init__.py +14 -0
- data_engine/authoring/builder.py +31 -0
- data_engine/authoring/execution/__init__.py +6 -0
- data_engine/authoring/execution/app.py +6 -0
- data_engine/authoring/execution/context.py +82 -0
- data_engine/authoring/execution/continuous.py +176 -0
- data_engine/authoring/execution/grouped.py +106 -0
- data_engine/authoring/execution/logging.py +83 -0
- data_engine/authoring/execution/polling.py +135 -0
- data_engine/authoring/execution/runner.py +210 -0
- data_engine/authoring/execution/single.py +171 -0
- data_engine/authoring/flow.py +361 -0
- data_engine/authoring/helpers.py +160 -0
- data_engine/authoring/model.py +59 -0
- data_engine/authoring/primitives.py +430 -0
- data_engine/authoring/services.py +42 -0
- data_engine/devtools/__init__.py +3 -0
- data_engine/devtools/project_ast_map.py +503 -0
- data_engine/docs/__init__.py +1 -0
- data_engine/docs/sphinx_source/_static/custom.css +13 -0
- data_engine/docs/sphinx_source/api.rst +42 -0
- data_engine/docs/sphinx_source/conf.py +37 -0
- data_engine/docs/sphinx_source/guides/app-runtime-and-workspaces.md +397 -0
- data_engine/docs/sphinx_source/guides/authoring-flow-modules.md +215 -0
- data_engine/docs/sphinx_source/guides/configuring-flows.md +185 -0
- data_engine/docs/sphinx_source/guides/core-concepts.md +208 -0
- data_engine/docs/sphinx_source/guides/database-methods.md +107 -0
- data_engine/docs/sphinx_source/guides/duckdb-helpers.md +462 -0
- data_engine/docs/sphinx_source/guides/flow-context.md +538 -0
- data_engine/docs/sphinx_source/guides/flow-methods.md +206 -0
- data_engine/docs/sphinx_source/guides/getting-started.md +271 -0
- data_engine/docs/sphinx_source/guides/project-inventory.md +5683 -0
- data_engine/docs/sphinx_source/guides/project-map.md +118 -0
- data_engine/docs/sphinx_source/guides/recipes.md +268 -0
- data_engine/docs/sphinx_source/index.rst +22 -0
- data_engine/domain/__init__.py +92 -0
- data_engine/domain/actions.py +69 -0
- data_engine/domain/catalog.py +128 -0
- data_engine/domain/details.py +214 -0
- data_engine/domain/diagnostics.py +56 -0
- data_engine/domain/errors.py +104 -0
- data_engine/domain/inspection.py +99 -0
- data_engine/domain/logs.py +118 -0
- data_engine/domain/operations.py +172 -0
- data_engine/domain/operator.py +72 -0
- data_engine/domain/runs.py +155 -0
- data_engine/domain/runtime.py +279 -0
- data_engine/domain/source_state.py +17 -0
- data_engine/domain/support.py +54 -0
- data_engine/domain/time.py +23 -0
- data_engine/domain/workspace.py +159 -0
- data_engine/flow_modules/__init__.py +1 -0
- data_engine/flow_modules/flow_module_compiler.py +179 -0
- data_engine/flow_modules/flow_module_loader.py +201 -0
- data_engine/helpers/__init__.py +25 -0
- data_engine/helpers/duckdb.py +705 -0
- data_engine/hosts/__init__.py +1 -0
- data_engine/hosts/daemon/__init__.py +23 -0
- data_engine/hosts/daemon/app.py +221 -0
- data_engine/hosts/daemon/bootstrap.py +69 -0
- data_engine/hosts/daemon/client.py +465 -0
- data_engine/hosts/daemon/commands.py +64 -0
- data_engine/hosts/daemon/composition.py +310 -0
- data_engine/hosts/daemon/constants.py +15 -0
- data_engine/hosts/daemon/entrypoints.py +97 -0
- data_engine/hosts/daemon/lifecycle.py +191 -0
- data_engine/hosts/daemon/manager.py +272 -0
- data_engine/hosts/daemon/ownership.py +126 -0
- data_engine/hosts/daemon/runtime_commands.py +188 -0
- data_engine/hosts/daemon/runtime_control.py +31 -0
- data_engine/hosts/daemon/server.py +84 -0
- data_engine/hosts/daemon/shared_state.py +147 -0
- data_engine/hosts/daemon/state_sync.py +101 -0
- data_engine/platform/__init__.py +1 -0
- data_engine/platform/identity.py +35 -0
- data_engine/platform/local_settings.py +146 -0
- data_engine/platform/theme.py +259 -0
- data_engine/platform/workspace_models.py +190 -0
- data_engine/platform/workspace_policy.py +333 -0
- data_engine/runtime/__init__.py +1 -0
- data_engine/runtime/file_watch.py +185 -0
- data_engine/runtime/ledger_models.py +116 -0
- data_engine/runtime/runtime_db.py +938 -0
- data_engine/runtime/shared_state.py +523 -0
- data_engine/services/__init__.py +49 -0
- data_engine/services/daemon.py +64 -0
- data_engine/services/daemon_state.py +40 -0
- data_engine/services/flow_catalog.py +102 -0
- data_engine/services/flow_execution.py +48 -0
- data_engine/services/ledger.py +85 -0
- data_engine/services/logs.py +65 -0
- data_engine/services/runtime_binding.py +105 -0
- data_engine/services/runtime_execution.py +126 -0
- data_engine/services/runtime_history.py +62 -0
- data_engine/services/settings.py +58 -0
- data_engine/services/shared_state.py +28 -0
- data_engine/services/theme.py +59 -0
- data_engine/services/workspace_provisioning.py +224 -0
- data_engine/services/workspaces.py +74 -0
- data_engine/ui/__init__.py +3 -0
- data_engine/ui/cli/__init__.py +19 -0
- data_engine/ui/cli/app.py +161 -0
- data_engine/ui/cli/commands_doctor.py +178 -0
- data_engine/ui/cli/commands_run.py +80 -0
- data_engine/ui/cli/commands_start.py +100 -0
- data_engine/ui/cli/commands_workspace.py +97 -0
- data_engine/ui/cli/dependencies.py +44 -0
- data_engine/ui/cli/parser.py +56 -0
- data_engine/ui/gui/__init__.py +25 -0
- data_engine/ui/gui/app.py +116 -0
- data_engine/ui/gui/bootstrap.py +487 -0
- data_engine/ui/gui/bootstrapper.py +140 -0
- data_engine/ui/gui/cache_models.py +23 -0
- data_engine/ui/gui/control_support.py +185 -0
- data_engine/ui/gui/controllers/__init__.py +6 -0
- data_engine/ui/gui/controllers/flows.py +439 -0
- data_engine/ui/gui/controllers/runtime.py +245 -0
- data_engine/ui/gui/dialogs/__init__.py +12 -0
- data_engine/ui/gui/dialogs/messages.py +88 -0
- data_engine/ui/gui/dialogs/previews.py +222 -0
- data_engine/ui/gui/helpers/__init__.py +62 -0
- data_engine/ui/gui/helpers/inspection.py +81 -0
- data_engine/ui/gui/helpers/lifecycle.py +112 -0
- data_engine/ui/gui/helpers/scroll.py +28 -0
- data_engine/ui/gui/helpers/theming.py +87 -0
- data_engine/ui/gui/icons/dark_light.svg +12 -0
- data_engine/ui/gui/icons/documentation.svg +1 -0
- data_engine/ui/gui/icons/failed.svg +3 -0
- data_engine/ui/gui/icons/group.svg +4 -0
- data_engine/ui/gui/icons/home.svg +2 -0
- data_engine/ui/gui/icons/manual.svg +2 -0
- data_engine/ui/gui/icons/poll.svg +2 -0
- data_engine/ui/gui/icons/schedule.svg +4 -0
- data_engine/ui/gui/icons/settings.svg +2 -0
- data_engine/ui/gui/icons/started.svg +3 -0
- data_engine/ui/gui/icons/success.svg +3 -0
- data_engine/ui/gui/icons/view-log.svg +3 -0
- data_engine/ui/gui/icons.py +50 -0
- data_engine/ui/gui/launcher.py +48 -0
- data_engine/ui/gui/presenters/__init__.py +72 -0
- data_engine/ui/gui/presenters/docs.py +140 -0
- data_engine/ui/gui/presenters/logs.py +58 -0
- data_engine/ui/gui/presenters/runtime_projection.py +29 -0
- data_engine/ui/gui/presenters/sidebar.py +88 -0
- data_engine/ui/gui/presenters/steps.py +148 -0
- data_engine/ui/gui/presenters/workspace.py +39 -0
- data_engine/ui/gui/presenters/workspace_binding.py +75 -0
- data_engine/ui/gui/presenters/workspace_settings.py +182 -0
- data_engine/ui/gui/preview_models.py +37 -0
- data_engine/ui/gui/render_support.py +241 -0
- data_engine/ui/gui/rendering/__init__.py +12 -0
- data_engine/ui/gui/rendering/artifacts.py +95 -0
- data_engine/ui/gui/rendering/icons.py +50 -0
- data_engine/ui/gui/runtime.py +47 -0
- data_engine/ui/gui/state_support.py +193 -0
- data_engine/ui/gui/support.py +214 -0
- data_engine/ui/gui/surface.py +209 -0
- data_engine/ui/gui/theme.py +720 -0
- data_engine/ui/gui/widgets/__init__.py +34 -0
- data_engine/ui/gui/widgets/config.py +41 -0
- data_engine/ui/gui/widgets/logs.py +62 -0
- data_engine/ui/gui/widgets/panels.py +507 -0
- data_engine/ui/gui/widgets/sidebar.py +130 -0
- data_engine/ui/gui/widgets/steps.py +84 -0
- data_engine/ui/tui/__init__.py +5 -0
- data_engine/ui/tui/app.py +222 -0
- data_engine/ui/tui/bootstrap.py +475 -0
- data_engine/ui/tui/bootstrapper.py +117 -0
- data_engine/ui/tui/controllers/__init__.py +6 -0
- data_engine/ui/tui/controllers/flows.py +349 -0
- data_engine/ui/tui/controllers/runtime.py +167 -0
- data_engine/ui/tui/runtime.py +34 -0
- data_engine/ui/tui/state_support.py +141 -0
- data_engine/ui/tui/support.py +63 -0
- data_engine/ui/tui/theme.py +204 -0
- data_engine/ui/tui/widgets.py +123 -0
- data_engine/views/__init__.py +109 -0
- data_engine/views/actions.py +80 -0
- data_engine/views/artifacts.py +58 -0
- data_engine/views/flow_display.py +69 -0
- data_engine/views/logs.py +54 -0
- data_engine/views/models.py +96 -0
- data_engine/views/presentation.py +133 -0
- data_engine/views/runs.py +62 -0
- data_engine/views/state.py +39 -0
- data_engine/views/status.py +13 -0
- data_engine/views/text.py +109 -0
- py_data_engine-0.1.0.dist-info/METADATA +330 -0
- py_data_engine-0.1.0.dist-info/RECORD +200 -0
- py_data_engine-0.1.0.dist-info/WHEEL +5 -0
- py_data_engine-0.1.0.dist-info/entry_points.txt +2 -0
- py_data_engine-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"""Bootstrap helpers for the desktop GUI application shell."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import threading
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from queue import Queue
|
|
10
|
+
from uuid import uuid4
|
|
11
|
+
from typing import TYPE_CHECKING
|
|
12
|
+
|
|
13
|
+
from PySide6.QtCore import QTimer
|
|
14
|
+
from PySide6.QtGui import QGuiApplication
|
|
15
|
+
|
|
16
|
+
from data_engine.domain import DaemonStatusState, FlowLogEntry, OperationSessionState, OperatorSessionState, StepOutputIndex
|
|
17
|
+
from data_engine.platform.identity import APP_DISPLAY_NAME, APP_INTERNAL_ID
|
|
18
|
+
from data_engine.platform.workspace_models import DATA_ENGINE_WORKSPACE_COLLECTION_ROOT_ENV_VAR
|
|
19
|
+
from data_engine.ui.gui.bootstrap import GuiServices
|
|
20
|
+
from data_engine.ui.gui.controllers import GuiFlowController, GuiRuntimeController
|
|
21
|
+
from data_engine.ui.gui.helpers import register_client_session as helper_register_client_session
|
|
22
|
+
from data_engine.ui.gui.runtime import QueueLogHandler, UiSignals
|
|
23
|
+
from data_engine.ui.gui.surface import build_default_gui_services
|
|
24
|
+
|
|
25
|
+
if TYPE_CHECKING:
|
|
26
|
+
from data_engine.ui.gui.app import DataEngineWindow
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def bootstrap_gui_window(window: "DataEngineWindow", *, theme_name: str, services: GuiServices | None = None) -> None:
|
|
30
|
+
"""Bind one GUI window to its services, runtime state, and timers."""
|
|
31
|
+
window.setWindowTitle(APP_DISPLAY_NAME)
|
|
32
|
+
window.resize(1480, 920)
|
|
33
|
+
window.setMinimumSize(1180, 760)
|
|
34
|
+
window.services = services or build_default_gui_services(theme_name)
|
|
35
|
+
window.workspace_service = window.services.workspace_service
|
|
36
|
+
window.action_state_application = window.services.action_state_application
|
|
37
|
+
window.detail_application = window.services.detail_application
|
|
38
|
+
window.daemon_service = window.services.daemon_service
|
|
39
|
+
window.daemon_state_service = window.services.daemon_state_service
|
|
40
|
+
window.runtime_application = window.services.runtime_application
|
|
41
|
+
window.control_application = window.services.control_application
|
|
42
|
+
window.ledger_service = window.services.ledger_service
|
|
43
|
+
window.log_service = window.services.log_service
|
|
44
|
+
window.runtime_binding_service = window.services.runtime_binding_service
|
|
45
|
+
window.runtime_history_service = window.services.runtime_history_service
|
|
46
|
+
window.shared_state_service = window.services.shared_state_service
|
|
47
|
+
window.settings_service = window.services.settings_service
|
|
48
|
+
window.theme_service = window.services.theme_service
|
|
49
|
+
window.workspace_provisioning_service = window.services.workspace_provisioning_service
|
|
50
|
+
window.workspace_session_application = window.services.workspace_session_application
|
|
51
|
+
window.flow_catalog_application = window.services.flow_catalog_application
|
|
52
|
+
window.flow_controller = GuiFlowController(
|
|
53
|
+
workspace_session_application=window.workspace_session_application,
|
|
54
|
+
flow_catalog_application=window.flow_catalog_application,
|
|
55
|
+
log_service=window.log_service,
|
|
56
|
+
)
|
|
57
|
+
window.runtime_controller = GuiRuntimeController(
|
|
58
|
+
runtime_application=window.runtime_application,
|
|
59
|
+
daemon_service=window.daemon_service,
|
|
60
|
+
log_service=window.log_service,
|
|
61
|
+
)
|
|
62
|
+
window.theme_name = window.theme_service.resolve_name(theme_name)
|
|
63
|
+
env_collection_root = os.environ.get(DATA_ENGINE_WORKSPACE_COLLECTION_ROOT_ENV_VAR)
|
|
64
|
+
initial_override = None if env_collection_root and env_collection_root.strip() else window.settings_service.workspace_collection_root()
|
|
65
|
+
window.workspace_paths = window.workspace_service.resolve_paths(
|
|
66
|
+
workspace_collection_root=initial_override,
|
|
67
|
+
)
|
|
68
|
+
window._operator_session_state = OperatorSessionState.from_paths(window.workspace_paths, override_root=initial_override)
|
|
69
|
+
window.workspace_session_state = window.workspace_session_application.refresh_session(
|
|
70
|
+
workspace_paths=window.workspace_paths,
|
|
71
|
+
override_root=initial_override,
|
|
72
|
+
)
|
|
73
|
+
window.client_session_id = uuid4().hex
|
|
74
|
+
|
|
75
|
+
window.log_queue: Queue[FlowLogEntry] = Queue()
|
|
76
|
+
window.log_handler = QueueLogHandler(window.log_queue)
|
|
77
|
+
logger = logging.getLogger(APP_INTERNAL_ID)
|
|
78
|
+
logger.addHandler(window.log_handler)
|
|
79
|
+
logger.setLevel(logging.INFO)
|
|
80
|
+
|
|
81
|
+
window.signals = UiSignals()
|
|
82
|
+
window.signals.run_finished.connect(window._finish_run)
|
|
83
|
+
window.signals.runtime_finished.connect(window._finish_runtime)
|
|
84
|
+
window.signals.docs_build_finished.connect(window._finish_docs_build)
|
|
85
|
+
window.signals.daemon_startup_finished.connect(window._finish_daemon_startup)
|
|
86
|
+
|
|
87
|
+
window.engine_runtime_stop_event = threading.Event()
|
|
88
|
+
window.engine_flow_stop_event = threading.Event()
|
|
89
|
+
window.manual_flow_stop_events: dict[str, threading.Event] = {}
|
|
90
|
+
window.operation_row_widgets = []
|
|
91
|
+
window.operation_tracker = OperationSessionState.empty()
|
|
92
|
+
window.operation_flash_timers: list[QTimer] = []
|
|
93
|
+
window.sidebar_flow_widgets: dict[str, QFrame] = {}
|
|
94
|
+
window.sidebar_group_widgets: dict[str, QFrame] = {}
|
|
95
|
+
window.step_output_index = StepOutputIndex.empty()
|
|
96
|
+
window.runtime_binding = window.runtime_binding_service.open_binding(window.workspace_paths)
|
|
97
|
+
helper_register_client_session(window)
|
|
98
|
+
window.output_preview_dialog = None
|
|
99
|
+
window.config_preview_dialog = None
|
|
100
|
+
window.run_log_preview_dialog = None
|
|
101
|
+
window._docs_root_dir = None
|
|
102
|
+
window.docs_uses_webengine = False
|
|
103
|
+
window._docs_build_running = False
|
|
104
|
+
window.ui_closing = False
|
|
105
|
+
window._log_view_refresh_pending = False
|
|
106
|
+
window._action_buttons_refresh_pending = False
|
|
107
|
+
window._worker_threads: set[threading.Thread] = set()
|
|
108
|
+
window._worker_threads_lock = threading.RLock()
|
|
109
|
+
window._daemon_status = DaemonStatusState.empty()
|
|
110
|
+
window._last_daemon_spawn_attempt = 0.0
|
|
111
|
+
window._auto_daemon_enabled = False
|
|
112
|
+
window._daemon_startup_in_progress = False
|
|
113
|
+
window._pending_message_box: tuple[str, str, str] | None = None
|
|
114
|
+
window._message_box_scheduled = False
|
|
115
|
+
window._message_box_open = False
|
|
116
|
+
window._message_box_generation = 0
|
|
117
|
+
window._workspace_switch_generation = 0
|
|
118
|
+
|
|
119
|
+
window._build_window()
|
|
120
|
+
window._reload_workspace_options()
|
|
121
|
+
window._load_flows()
|
|
122
|
+
style_hints = QGuiApplication.styleHints()
|
|
123
|
+
if hasattr(style_hints, "colorSchemeChanged"):
|
|
124
|
+
style_hints.colorSchemeChanged.connect(window._sync_theme_to_system)
|
|
125
|
+
|
|
126
|
+
window.log_timer = QTimer(window)
|
|
127
|
+
window.log_timer.timeout.connect(window._poll_log_queue)
|
|
128
|
+
window.log_timer.start(50)
|
|
129
|
+
window.ui_refresh_timer = QTimer(window)
|
|
130
|
+
window.ui_refresh_timer.setSingleShot(True)
|
|
131
|
+
window.ui_refresh_timer.timeout.connect(window._flush_deferred_ui_updates)
|
|
132
|
+
window.operation_timer = QTimer(window)
|
|
133
|
+
window.operation_timer.timeout.connect(window._refresh_live_operation_durations)
|
|
134
|
+
window.operation_timer.start(100)
|
|
135
|
+
window.daemon_timer = QTimer(window)
|
|
136
|
+
window.daemon_timer.timeout.connect(window._sync_from_daemon)
|
|
137
|
+
window.daemon_timer.start(500)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
__all__ = ["bootstrap_gui_window"]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Explicit GUI-local cache models."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from PySide6.QtWidgets import QFrame, QLabel, QPushButton
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class OperationRowWidgets:
|
|
14
|
+
"""Cached widget references for one operation row."""
|
|
15
|
+
|
|
16
|
+
row_card: "QFrame"
|
|
17
|
+
title_label: "QLabel"
|
|
18
|
+
duration_label: "QLabel"
|
|
19
|
+
inspect_button: "QPushButton | None"
|
|
20
|
+
operation_name: str
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
__all__ = ["OperationRowWidgets"]
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"""Flow, runtime, and log coordination helpers for the GUI shell."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
7
|
+
from data_engine.domain import FlowLogEntry, FlowRunState, RuntimeStepEvent
|
|
8
|
+
from data_engine.ui.gui.dialogs import show_run_log_preview
|
|
9
|
+
from data_engine.ui.gui.preview_models import RunLogPreviewRequest
|
|
10
|
+
from data_engine.ui.gui.presenters import (
|
|
11
|
+
add_log_run_item as present_add_log_run_item,
|
|
12
|
+
apply_daemon_snapshot as present_apply_daemon_snapshot,
|
|
13
|
+
finish_daemon_startup as present_finish_daemon_startup,
|
|
14
|
+
refresh_log_view as present_refresh_log_view,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from data_engine.ui.gui.app import DataEngineWindow
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class GuiControlMixin:
|
|
22
|
+
"""Shell coordination helpers for flows, runtime, daemon, and log refresh."""
|
|
23
|
+
|
|
24
|
+
def _load_flows(self: "DataEngineWindow") -> None:
|
|
25
|
+
self.flow_controller.load_flows(self)
|
|
26
|
+
|
|
27
|
+
def _populate_flow_tree(self: "DataEngineWindow") -> None:
|
|
28
|
+
self.flow_controller.populate_flow_tree(self)
|
|
29
|
+
|
|
30
|
+
def _select_flow(self: "DataEngineWindow", flow_name: str | None) -> None:
|
|
31
|
+
self.flow_controller.select_flow(self, flow_name)
|
|
32
|
+
|
|
33
|
+
def _refresh_selection(self: "DataEngineWindow", card) -> None:
|
|
34
|
+
self.flow_controller.refresh_selection(self, card)
|
|
35
|
+
|
|
36
|
+
def _refresh_summary(self: "DataEngineWindow") -> None:
|
|
37
|
+
self.flow_controller.refresh_summary(self)
|
|
38
|
+
|
|
39
|
+
def _refresh_action_buttons(self: "DataEngineWindow") -> None:
|
|
40
|
+
self.flow_controller.refresh_action_buttons(self)
|
|
41
|
+
|
|
42
|
+
def _reload_workspace_options(self: "DataEngineWindow") -> None:
|
|
43
|
+
self.flow_controller.reload_workspace_options(self)
|
|
44
|
+
|
|
45
|
+
def _workspace_selection_changed(self: "DataEngineWindow", index: int) -> None:
|
|
46
|
+
self.flow_controller.workspace_selection_changed(self, index)
|
|
47
|
+
|
|
48
|
+
def _switch_workspace(self: "DataEngineWindow", workspace_id: str) -> None:
|
|
49
|
+
self.flow_controller.switch_workspace(self, workspace_id)
|
|
50
|
+
|
|
51
|
+
def _refresh_lease_status(self: "DataEngineWindow") -> None:
|
|
52
|
+
self.flow_controller.refresh_lease_status(self)
|
|
53
|
+
|
|
54
|
+
def _request_control(self: "DataEngineWindow") -> None:
|
|
55
|
+
self.flow_controller.request_control(self)
|
|
56
|
+
|
|
57
|
+
def _update_engine_button(self: "DataEngineWindow") -> None:
|
|
58
|
+
self.flow_controller.update_engine_button(self)
|
|
59
|
+
|
|
60
|
+
def _set_flow_state(self: "DataEngineWindow", flow_name: str, state: str) -> None:
|
|
61
|
+
self.flow_controller.set_flow_state(self, flow_name, state)
|
|
62
|
+
|
|
63
|
+
def _set_flow_states(self: "DataEngineWindow", updates: dict[str, str]) -> None:
|
|
64
|
+
self.flow_controller.set_flow_states(self, updates)
|
|
65
|
+
|
|
66
|
+
def _sync_from_daemon(self: "DataEngineWindow") -> None:
|
|
67
|
+
self.runtime_controller.sync_from_daemon(self)
|
|
68
|
+
|
|
69
|
+
def _ensure_daemon_started(self: "DataEngineWindow") -> bool:
|
|
70
|
+
return self.runtime_controller.ensure_daemon_started(self)
|
|
71
|
+
|
|
72
|
+
def _start_daemon_worker(self: "DataEngineWindow") -> None:
|
|
73
|
+
self.runtime_controller.start_daemon_worker(self)
|
|
74
|
+
|
|
75
|
+
def _finish_daemon_startup(self: "DataEngineWindow", success: bool, error_text: str) -> None:
|
|
76
|
+
present_finish_daemon_startup(self, success, error_text)
|
|
77
|
+
|
|
78
|
+
def _apply_daemon_snapshot(self: "DataEngineWindow", snapshot) -> None:
|
|
79
|
+
present_apply_daemon_snapshot(self, snapshot)
|
|
80
|
+
|
|
81
|
+
def _rebuild_runtime_snapshot(self: "DataEngineWindow") -> None:
|
|
82
|
+
self.runtime_controller.rebuild_runtime_snapshot(self)
|
|
83
|
+
|
|
84
|
+
def _refresh_log_view(self: "DataEngineWindow", *, force_scroll_to_bottom: bool = False) -> None:
|
|
85
|
+
present_refresh_log_view(self, force_scroll_to_bottom=force_scroll_to_bottom)
|
|
86
|
+
|
|
87
|
+
def _add_log_run_item(self: "DataEngineWindow", run_group: FlowRunState) -> None:
|
|
88
|
+
present_add_log_run_item(self, run_group)
|
|
89
|
+
|
|
90
|
+
def _refresh_flows_requested(self: "DataEngineWindow") -> None:
|
|
91
|
+
self.flow_controller.refresh_flows_requested(self)
|
|
92
|
+
|
|
93
|
+
def _clear_logs(self: "DataEngineWindow") -> None:
|
|
94
|
+
self.flow_controller.clear_logs(self)
|
|
95
|
+
|
|
96
|
+
def _poll_log_queue(self: "DataEngineWindow") -> None:
|
|
97
|
+
from data_engine.ui.gui.surface import poll_log_queue as surface_poll_log_queue
|
|
98
|
+
|
|
99
|
+
surface_poll_log_queue(self)
|
|
100
|
+
|
|
101
|
+
def _show_run_log_preview(self: "DataEngineWindow", run_group: FlowRunState) -> None:
|
|
102
|
+
self.run_log_preview_dialog = show_run_log_preview(self, RunLogPreviewRequest.from_run(run_group))
|
|
103
|
+
|
|
104
|
+
def _show_run_error_details(self: "DataEngineWindow", run_group: FlowRunState, entry: FlowLogEntry) -> None:
|
|
105
|
+
"""Show persisted failure detail for one failed run or step entry."""
|
|
106
|
+
event = entry.event
|
|
107
|
+
title, detail_text = self.runtime_history_service.error_text_for_entry(
|
|
108
|
+
self.runtime_binding.runtime_ledger,
|
|
109
|
+
run_group,
|
|
110
|
+
entry,
|
|
111
|
+
)
|
|
112
|
+
if event is not None and event.step_name is not None:
|
|
113
|
+
fallback_text = (
|
|
114
|
+
f'No persisted error detail was available for failed step "{event.step_name}" '
|
|
115
|
+
f'in run "{run_group.key[0]}".'
|
|
116
|
+
)
|
|
117
|
+
else:
|
|
118
|
+
fallback_text = f'No persisted error detail was available for failed run "{run_group.key[0]}".'
|
|
119
|
+
self._show_message_box(
|
|
120
|
+
title=title,
|
|
121
|
+
text=detail_text.strip() if isinstance(detail_text, str) and detail_text.strip() else fallback_text,
|
|
122
|
+
tone="error",
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
def _run_selected_flow(self: "DataEngineWindow") -> None:
|
|
126
|
+
if not self._has_authored_workspace():
|
|
127
|
+
self._sync_from_daemon()
|
|
128
|
+
return
|
|
129
|
+
card = self.flow_cards.get(self.selected_flow_name or "")
|
|
130
|
+
result = self.control_application.run_selected_flow(
|
|
131
|
+
paths=self.workspace_paths,
|
|
132
|
+
runtime_session=self.runtime_session,
|
|
133
|
+
selected_flow_name=card.name if card is not None else None,
|
|
134
|
+
selected_flow_valid=bool(card is not None and card.valid),
|
|
135
|
+
selected_flow_group=card.group if card is not None else None,
|
|
136
|
+
selected_flow_group_active=bool(card is not None and self._is_group_active(card.group)),
|
|
137
|
+
blocked_status_text=self.workspace_control_state.blocked_status_text,
|
|
138
|
+
timeout=2.0,
|
|
139
|
+
)
|
|
140
|
+
if result.error_text is not None:
|
|
141
|
+
self._show_message_box_later(
|
|
142
|
+
title="Data Engine",
|
|
143
|
+
text=result.error_text,
|
|
144
|
+
tone="error",
|
|
145
|
+
)
|
|
146
|
+
return
|
|
147
|
+
if not result.requested or card is None:
|
|
148
|
+
return
|
|
149
|
+
self._append_log_line(f"Starting one-time flow run: {card.name}", flow_name=card.name)
|
|
150
|
+
if result.sync_after:
|
|
151
|
+
self._sync_from_daemon()
|
|
152
|
+
|
|
153
|
+
def _start_runtime(self: "DataEngineWindow") -> None:
|
|
154
|
+
self.runtime_controller.start_runtime(self)
|
|
155
|
+
|
|
156
|
+
def _stop_runtime(self: "DataEngineWindow") -> None:
|
|
157
|
+
self.runtime_controller.stop_runtime(self)
|
|
158
|
+
|
|
159
|
+
def _toggle_runtime(self: "DataEngineWindow") -> None:
|
|
160
|
+
self.runtime_controller.toggle_runtime(self)
|
|
161
|
+
|
|
162
|
+
def _stop_pipeline(self: "DataEngineWindow") -> None:
|
|
163
|
+
self.runtime_controller.stop_pipeline(self)
|
|
164
|
+
|
|
165
|
+
def _safe_emit_run_finished(self: "DataEngineWindow", flow_name: str, results: object, error: object) -> None:
|
|
166
|
+
from data_engine.ui.gui.surface import safe_emit_run_finished as surface_safe_emit_run_finished
|
|
167
|
+
|
|
168
|
+
surface_safe_emit_run_finished(self, flow_name, results, error)
|
|
169
|
+
|
|
170
|
+
def _safe_emit_runtime_finished(self: "DataEngineWindow", flow_names: tuple[str, ...], results: object, error: object) -> None:
|
|
171
|
+
from data_engine.ui.gui.surface import safe_emit_runtime_finished as surface_safe_emit_runtime_finished
|
|
172
|
+
|
|
173
|
+
surface_safe_emit_runtime_finished(self, flow_names, results, error)
|
|
174
|
+
|
|
175
|
+
def _finish_run(self: "DataEngineWindow", flow_name: object, results: object, error: object) -> None:
|
|
176
|
+
self.runtime_controller.finish_run(self, flow_name, results, error)
|
|
177
|
+
|
|
178
|
+
def _finish_runtime(self: "DataEngineWindow", flow_names: object, results: object, error: object) -> None:
|
|
179
|
+
self.runtime_controller.finish_runtime(self, flow_names, results, error)
|
|
180
|
+
|
|
181
|
+
def _is_group_active(self: "DataEngineWindow", group_name: str) -> bool:
|
|
182
|
+
return self.runtime_controller.is_group_active(self, group_name)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
__all__ = ["GuiControlMixin"]
|