python-tty 0.1.3__tar.gz → 0.1.4__tar.gz
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.
- {python_tty-0.1.3/src/python_tty.egg-info → python_tty-0.1.4}/PKG-INFO +1 -1
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/config/config.py +3 -1
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/consoles/core.py +2 -1
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/executor/executor.py +33 -8
- {python_tty-0.1.3 → python_tty-0.1.4/src/python_tty.egg-info}/PKG-INFO +1 -1
- {python_tty-0.1.3 → python_tty-0.1.4}/.github/workflows/python-publish.yml +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/.gitignore +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/LICENSE +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/MANIFEST.in +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/NOTICE +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/README.md +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/README_zh.md +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/demos/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/demos/chat_room/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/demos/file_manager/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/demos/file_manager/commands/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/demos/file_manager/commands/root_commands.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/demos/file_manager/consoles/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/demos/file_manager/consoles/root.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/demos/file_manager/core/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/demos/file_manager/core/file_manager.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/demos/file_manager/exceptions/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/demos/file_manager/exceptions/console_exception.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/demos/file_manager/main.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/demos/file_manager/setup.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/demos/file_manager/utils/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/demos/file_manager/utils/table.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/docs/LOG.md +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/docs/context.md +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/pyproject.toml +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/requirements.txt +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/setup.cfg +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/setup.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/commands/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/commands/core.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/commands/decorators.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/commands/examples/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/commands/examples/root_commands.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/commands/examples/sub_commands.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/commands/general.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/commands/mixins.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/commands/registry.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/config/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/console_factory.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/consoles/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/consoles/decorators.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/consoles/examples/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/consoles/examples/root_console.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/consoles/examples/sub_console.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/consoles/loader.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/consoles/manager.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/consoles/registry.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/exceptions/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/exceptions/console_exception.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/executor/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/executor/models.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/frontends/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/meta/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/ui/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/ui/events.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/ui/output.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/utils/__init__.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/utils/table.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/utils/tokenize.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty/utils/ui_logger.py +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty.egg-info/SOURCES.txt +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty.egg-info/dependency_links.txt +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty.egg-info/requires.txt +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/src/python_tty.egg-info/top_level.txt +0 -0
- {python_tty-0.1.3 → python_tty-0.1.4}/tests/__init__.py +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from dataclasses import dataclass, field
|
|
2
|
-
from typing import Optional, TYPE_CHECKING
|
|
2
|
+
from typing import Optional, TYPE_CHECKING, Tuple, Type
|
|
3
3
|
|
|
4
4
|
if TYPE_CHECKING:
|
|
5
5
|
from python_tty.ui.output import OutputRouter
|
|
@@ -11,6 +11,8 @@ class ExecutorConfig:
|
|
|
11
11
|
retain_last_n: Optional[int] = None
|
|
12
12
|
ttl_seconds: Optional[float] = None
|
|
13
13
|
pop_on_wait: bool = False
|
|
14
|
+
exempt_exceptions: Optional[Tuple[Type[BaseException], ...]] = None
|
|
15
|
+
emit_run_events: bool = False
|
|
14
16
|
|
|
15
17
|
|
|
16
18
|
@dataclass
|
|
@@ -70,7 +70,8 @@ class BaseConsole(ABC, UIEventListener):
|
|
|
70
70
|
if executor is None:
|
|
71
71
|
self.run(invocation)
|
|
72
72
|
return
|
|
73
|
-
executor.submit_threadsafe(invocation, handler=self.run)
|
|
73
|
+
run_id = executor.submit_threadsafe(invocation, handler=self.run)
|
|
74
|
+
executor.wait_result_sync(run_id)
|
|
74
75
|
except ValueError:
|
|
75
76
|
return
|
|
76
77
|
|
|
@@ -9,6 +9,7 @@ from python_tty.config import ExecutorConfig
|
|
|
9
9
|
from python_tty.ui.events import UIEvent, UIEventLevel
|
|
10
10
|
from python_tty.ui.output import get_output_router
|
|
11
11
|
from python_tty.executor.models import Invocation, RunState, RunStatus
|
|
12
|
+
from python_tty.exceptions.console_exception import ConsoleExit, SubConsoleExit
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
@dataclass
|
|
@@ -33,6 +34,11 @@ class CommandExecutor:
|
|
|
33
34
|
self._retain_last_n = config.retain_last_n
|
|
34
35
|
self._ttl_seconds = config.ttl_seconds
|
|
35
36
|
self._pop_on_wait = config.pop_on_wait
|
|
37
|
+
self._emit_run_events = config.emit_run_events
|
|
38
|
+
if config.exempt_exceptions is None:
|
|
39
|
+
self._exempt_exceptions = (ConsoleExit, SubConsoleExit)
|
|
40
|
+
else:
|
|
41
|
+
self._exempt_exceptions = tuple(config.exempt_exceptions)
|
|
36
42
|
self._output_router = get_output_router()
|
|
37
43
|
|
|
38
44
|
@property
|
|
@@ -187,21 +193,29 @@ class CommandExecutor:
|
|
|
187
193
|
return
|
|
188
194
|
run_state.status = RunStatus.RUNNING
|
|
189
195
|
run_state.started_at = time.time()
|
|
190
|
-
self.
|
|
196
|
+
self._emit_run_event(run_state.run_id, "start", UIEventLevel.INFO)
|
|
191
197
|
try:
|
|
192
198
|
result = work_item.handler(work_item.invocation)
|
|
193
199
|
if inspect.isawaitable(result):
|
|
194
200
|
result = await result
|
|
195
201
|
run_state.result = result
|
|
196
202
|
run_state.status = RunStatus.SUCCEEDED
|
|
197
|
-
self.
|
|
203
|
+
self._emit_run_event(run_state.run_id, "success", UIEventLevel.SUCCESS)
|
|
198
204
|
self._resolve_future(run_state, result=result)
|
|
205
|
+
except self._exempt_exceptions as exc:
|
|
206
|
+
run_state.error = exc
|
|
207
|
+
run_state.status = RunStatus.CANCELLED
|
|
208
|
+
self._emit_run_event(run_state.run_id, "cancelled", UIEventLevel.INFO)
|
|
209
|
+
self._resolve_future(run_state, error=exc)
|
|
199
210
|
except Exception as exc:
|
|
200
211
|
run_state.error = exc
|
|
201
212
|
run_state.status = RunStatus.FAILED
|
|
202
|
-
self.
|
|
213
|
+
self._emit_run_event(
|
|
203
214
|
run_state.run_id,
|
|
204
|
-
|
|
215
|
+
"failure",
|
|
216
|
+
UIEventLevel.ERROR,
|
|
217
|
+
payload={"error": str(exc)},
|
|
218
|
+
force=True,
|
|
205
219
|
)
|
|
206
220
|
self._resolve_future(run_state, error=exc)
|
|
207
221
|
finally:
|
|
@@ -223,20 +237,27 @@ class CommandExecutor:
|
|
|
223
237
|
return
|
|
224
238
|
run_state.status = RunStatus.RUNNING
|
|
225
239
|
run_state.started_at = time.time()
|
|
226
|
-
self.
|
|
240
|
+
self._emit_run_event(run_state.run_id, "start", UIEventLevel.INFO)
|
|
227
241
|
try:
|
|
228
242
|
result = handler(invocation)
|
|
229
243
|
if inspect.isawaitable(result):
|
|
230
244
|
result = self._run_awaitable_inline(result)
|
|
231
245
|
run_state.result = result
|
|
232
246
|
run_state.status = RunStatus.SUCCEEDED
|
|
233
|
-
self.
|
|
247
|
+
self._emit_run_event(run_state.run_id, "success", UIEventLevel.SUCCESS)
|
|
248
|
+
except self._exempt_exceptions as exc:
|
|
249
|
+
run_state.error = exc
|
|
250
|
+
run_state.status = RunStatus.CANCELLED
|
|
251
|
+
self._emit_run_event(run_state.run_id, "cancelled", UIEventLevel.INFO)
|
|
234
252
|
except Exception as exc:
|
|
235
253
|
run_state.error = exc
|
|
236
254
|
run_state.status = RunStatus.FAILED
|
|
237
|
-
self.
|
|
255
|
+
self._emit_run_event(
|
|
238
256
|
run_state.run_id,
|
|
239
|
-
|
|
257
|
+
"failure",
|
|
258
|
+
UIEventLevel.ERROR,
|
|
259
|
+
payload={"error": str(exc)},
|
|
260
|
+
force=True,
|
|
240
261
|
)
|
|
241
262
|
finally:
|
|
242
263
|
run_state.finished_at = time.time()
|
|
@@ -246,6 +267,10 @@ class CommandExecutor:
|
|
|
246
267
|
def _build_run_event(event_type: str, level: UIEventLevel, payload=None):
|
|
247
268
|
return UIEvent(msg=event_type, level=level, event_type=event_type, payload=payload)
|
|
248
269
|
|
|
270
|
+
def _emit_run_event(self, run_id: str, event_type: str, level: UIEventLevel, payload=None, force: bool = False):
|
|
271
|
+
if force or self._emit_run_events:
|
|
272
|
+
self.publish_event(run_id, self._build_run_event(event_type, level, payload=payload))
|
|
273
|
+
|
|
249
274
|
@staticmethod
|
|
250
275
|
def _missing_handler(invocation: Invocation):
|
|
251
276
|
raise RuntimeError("No handler provided for invocation execution")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|