palmengine 0.7.4__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.
- palm/__init__.py +23 -0
- palm/app/__init__.py +22 -0
- palm/app/app.py +356 -0
- palm/app/bootstrap.py +124 -0
- palm/app/cli_settings.py +63 -0
- palm/app/registry.py +72 -0
- palm/app/resolvers.py +43 -0
- palm/app/session.py +67 -0
- palm/app/settings.py +61 -0
- palm/backends/__init__.py +5 -0
- palm/backends/behavior_tree/__init__.py +7 -0
- palm/backends/behavior_tree/runner.py +68 -0
- palm/common/__init__.py +91 -0
- palm/common/exceptions.py +50 -0
- palm/common/executions/__init__.py +12 -0
- palm/common/executions/executor.py +413 -0
- palm/common/executions/flow_submission.py +114 -0
- palm/common/executions/process_submission.py +55 -0
- palm/common/hooks/__init__.py +6 -0
- palm/common/hooks/instance_persistence.py +68 -0
- palm/common/hooks/state_snapshot.py +72 -0
- palm/common/managers/__init__.py +15 -0
- palm/common/managers/base.py +25 -0
- palm/common/managers/instance_manager.py +341 -0
- palm/common/patterns/__init__.py +6 -0
- palm/common/patterns/build_context.py +23 -0
- palm/common/patterns/builder.py +51 -0
- palm/common/persistence/__init__.py +23 -0
- palm/common/persistence/definition_repository.py +299 -0
- palm/common/persistence/instance_repository.py +193 -0
- palm/common/persistence/instance_resume.py +16 -0
- palm/common/persistence/instance_sync.py +110 -0
- palm/common/plans/__init__.py +7 -0
- palm/common/plans/execution_plan.py +59 -0
- palm/common/plans/process_plan.py +32 -0
- palm/common/plans/registry.py +68 -0
- palm/common/storage/__init__.py +5 -0
- palm/common/storage/factory.py +141 -0
- palm/core/__init__.py +112 -0
- palm/core/auth/__init__.py +9 -0
- palm/core/auth/engine.py +57 -0
- palm/core/base.py +54 -0
- palm/core/behavior_tree/__init__.py +58 -0
- palm/core/behavior_tree/base.py +92 -0
- palm/core/behavior_tree/base_pattern.py +39 -0
- palm/core/behavior_tree/composite.py +24 -0
- palm/core/behavior_tree/decorator.py +37 -0
- palm/core/behavior_tree/engine.py +118 -0
- palm/core/behavior_tree/exceptions.py +21 -0
- palm/core/behavior_tree/leaf.py +20 -0
- palm/core/behavior_tree/nodes/__init__.py +27 -0
- palm/core/behavior_tree/nodes/composite/__init__.py +10 -0
- palm/core/behavior_tree/nodes/composite/parallel_node.py +74 -0
- palm/core/behavior_tree/nodes/composite/selector_node.py +35 -0
- palm/core/behavior_tree/nodes/composite/sequence_node.py +35 -0
- palm/core/behavior_tree/nodes/decorator/__init__.py +7 -0
- palm/core/behavior_tree/nodes/decorator/inverter_node.py +21 -0
- palm/core/behavior_tree/nodes/decorator/repeat_node.py +38 -0
- palm/core/behavior_tree/nodes/decorator/retry_node.py +33 -0
- palm/core/behavior_tree/nodes/leaf/__init__.py +11 -0
- palm/core/behavior_tree/nodes/leaf/action_node.py +31 -0
- palm/core/behavior_tree/nodes/leaf/condition_node.py +26 -0
- palm/core/behavior_tree/nodes/leaf/interactive_leaf.py +45 -0
- palm/core/behavior_tree/root.py +19 -0
- palm/core/context/__init__.py +10 -0
- palm/core/context/base_state.py +43 -0
- palm/core/context/engine.py +110 -0
- palm/core/event/__init__.py +9 -0
- palm/core/event/engine.py +52 -0
- palm/core/exceptions.py +56 -0
- palm/core/orchestration/__init__.py +35 -0
- palm/core/orchestration/drive.py +38 -0
- palm/core/orchestration/engine.py +316 -0
- palm/core/orchestration/events.py +17 -0
- palm/core/orchestration/exceptions.py +47 -0
- palm/core/orchestration/execution/__init__.py +5 -0
- palm/core/orchestration/execution/base_runner.py +18 -0
- palm/core/orchestration/execution_context.py +16 -0
- palm/core/orchestration/hooks.py +65 -0
- palm/core/orchestration/input_capable.py +26 -0
- palm/core/orchestration/job.py +142 -0
- palm/core/orchestration/job_state.py +40 -0
- palm/core/orchestration/mode/__init__.py +8 -0
- palm/core/orchestration/mode/base_mode.py +52 -0
- palm/core/orchestration/mode/unconfigured_mode.py +41 -0
- palm/core/orchestration/run_result.py +24 -0
- palm/core/registry.py +73 -0
- palm/core/resource/__init__.py +10 -0
- palm/core/resource/base_provider.py +29 -0
- palm/core/resource/engine.py +39 -0
- palm/core/storage/__init__.py +10 -0
- palm/core/storage/base_backend.py +53 -0
- palm/core/storage/engine.py +93 -0
- palm/definitions/__init__.py +10 -0
- palm/definitions/flow.py +67 -0
- palm/definitions/process.py +70 -0
- palm/instances/__init__.py +9 -0
- palm/instances/process_instance.py +113 -0
- palm/instances/state_snapshot.py +80 -0
- palm/instances/status_history.py +42 -0
- palm/patterns/__init__.py +15 -0
- palm/patterns/_apps.py +18 -0
- palm/patterns/_registry.py +134 -0
- palm/patterns/dag/__init__.py +10 -0
- palm/patterns/dag/builder.py +26 -0
- palm/patterns/dag/pattern.py +21 -0
- palm/patterns/dag/registry.py +9 -0
- palm/patterns/etl/__init__.py +10 -0
- palm/patterns/etl/builder.py +26 -0
- palm/patterns/etl/pattern.py +26 -0
- palm/patterns/etl/registry.py +9 -0
- palm/patterns/wizard/__init__.py +63 -0
- palm/patterns/wizard/action_leaf.py +94 -0
- palm/patterns/wizard/backtrack.py +71 -0
- palm/patterns/wizard/base.py +10 -0
- palm/patterns/wizard/builder.py +170 -0
- palm/patterns/wizard/commit_leaf.py +113 -0
- palm/patterns/wizard/config.py +156 -0
- palm/patterns/wizard/events.py +19 -0
- palm/patterns/wizard/handler.py +94 -0
- palm/patterns/wizard/keys.py +23 -0
- palm/patterns/wizard/options.py +66 -0
- palm/patterns/wizard/pattern.py +143 -0
- palm/patterns/wizard/persistence.py +54 -0
- palm/patterns/wizard/registry.py +24 -0
- palm/patterns/wizard/resume.py +34 -0
- palm/patterns/wizard/step_kinds.py +13 -0
- palm/patterns/wizard/step_leaf.py +98 -0
- palm/patterns/wizard/submission.py +21 -0
- palm/patterns/wizard/summary_leaf.py +78 -0
- palm/patterns/wizard/tree.py +78 -0
- palm/patterns/wizard/validation.py +137 -0
- palm/providers/__init__.py +13 -0
- palm/providers/_apps.py +14 -0
- palm/providers/graphql/__init__.py +6 -0
- palm/providers/graphql/provider.py +20 -0
- palm/providers/graphql/registry.py +6 -0
- palm/providers/postgres/__init__.py +6 -0
- palm/providers/postgres/provider.py +20 -0
- palm/providers/postgres/registry.py +6 -0
- palm/providers/rest/__init__.py +6 -0
- palm/providers/rest/provider.py +20 -0
- palm/providers/rest/registry.py +6 -0
- palm/runtimes/__init__.py +24 -0
- palm/runtimes/base.py +290 -0
- palm/runtimes/cli.py +118 -0
- palm/runtimes/cli_pkg/__init__.py +6 -0
- palm/runtimes/cli_pkg/actions.py +68 -0
- palm/runtimes/cli_pkg/args.py +211 -0
- palm/runtimes/cli_pkg/bootstrap.py +53 -0
- palm/runtimes/cli_pkg/commands/__init__.py +5 -0
- palm/runtimes/cli_pkg/commands/registry.py +413 -0
- palm/runtimes/cli_pkg/completion.py +184 -0
- palm/runtimes/cli_pkg/context.py +80 -0
- palm/runtimes/cli_pkg/display.py +178 -0
- palm/runtimes/cli_pkg/doctor.py +112 -0
- palm/runtimes/cli_pkg/instance_ops.py +126 -0
- palm/runtimes/cli_pkg/instances.py +52 -0
- palm/runtimes/cli_pkg/output.py +33 -0
- palm/runtimes/cli_pkg/repl.py +88 -0
- palm/runtimes/cli_pkg/settings.py +5 -0
- palm/runtimes/cli_pkg/startup.py +67 -0
- palm/runtimes/cli_pkg/version_info.py +59 -0
- palm/runtimes/daemon.py +46 -0
- palm/runtimes/embedded.py +27 -0
- palm/runtimes/hooks.py +115 -0
- palm/runtimes/host.py +41 -0
- palm/runtimes/schedulers/__init__.py +6 -0
- palm/runtimes/schedulers/inline.py +61 -0
- palm/runtimes/schedulers/queued.py +133 -0
- palm/runtimes/server/__init__.py +6 -0
- palm/runtimes/server/auth.py +37 -0
- palm/runtimes/server/http.py +281 -0
- palm/runtimes/server/runtime.py +195 -0
- palm/runtimes/wiring.py +59 -0
- palm/states/__init__.py +10 -0
- palm/states/blackboard_state.py +40 -0
- palm/storages/__init__.py +21 -0
- palm/storages/_apps.py +20 -0
- palm/storages/filesystem/__init__.py +6 -0
- palm/storages/filesystem/backend.py +175 -0
- palm/storages/filesystem/registry.py +6 -0
- palm/storages/memory/__init__.py +6 -0
- palm/storages/memory/backend.py +42 -0
- palm/storages/memory/registry.py +6 -0
- palm/storages/mongodb/__init__.py +6 -0
- palm/storages/mongodb/backend.py +81 -0
- palm/storages/mongodb/registry.py +6 -0
- palm/storages/postgres/__init__.py +6 -0
- palm/storages/postgres/backend.py +36 -0
- palm/storages/postgres/registry.py +6 -0
- palm/utils/__init__.py +5 -0
- palmengine-0.7.4.dist-info/METADATA +370 -0
- palmengine-0.7.4.dist-info/RECORD +196 -0
- palmengine-0.7.4.dist-info/WHEEL +4 -0
- palmengine-0.7.4.dist-info/entry_points.txt +2 -0
palm/app/resolvers.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Definition reference resolution — shared by library and CLI callers.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
|
+
|
|
9
|
+
from palm.common.exceptions import DefinitionNotFoundError
|
|
10
|
+
from palm.definitions.flow import FlowDefinition
|
|
11
|
+
from palm.definitions.process import ProcessDefinition
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from palm.app.app import PalmApp
|
|
15
|
+
from palm.common.persistence.definition_repository import DefinitionRepository
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def resolve_flow(repository: DefinitionRepository, ref: str) -> FlowDefinition:
|
|
19
|
+
"""Resolve a flow by display name, falling back to definition id."""
|
|
20
|
+
try:
|
|
21
|
+
return repository.get_flow(ref)
|
|
22
|
+
except DefinitionNotFoundError:
|
|
23
|
+
return repository.get_flow(ref, by_id=True)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def resolve_process(repository: DefinitionRepository, ref: str) -> ProcessDefinition:
|
|
27
|
+
"""Resolve a process by display name, falling back to definition id."""
|
|
28
|
+
try:
|
|
29
|
+
return repository.get_process(ref)
|
|
30
|
+
except DefinitionNotFoundError:
|
|
31
|
+
return repository.get_process(ref, by_id=True)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def resolve_flow_for_app(app: PalmApp, ref: str, *, runtime_name: str | None = None) -> FlowDefinition:
|
|
35
|
+
"""Resolve a flow via a :class:`~palm.app.app.PalmApp` runtime repository."""
|
|
36
|
+
return resolve_flow(app.repository(runtime_name=runtime_name), ref)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def resolve_process_for_app(
|
|
40
|
+
app: PalmApp, ref: str, *, runtime_name: str | None = None
|
|
41
|
+
) -> ProcessDefinition:
|
|
42
|
+
"""Resolve a process via a :class:`~palm.app.app.PalmApp` runtime repository."""
|
|
43
|
+
return resolve_process(app.repository(runtime_name=runtime_name), ref)
|
palm/app/session.py
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CLI session bootstrap — thin PalmApp client for terminal entrypoints.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from palm.app.app import PalmApp
|
|
11
|
+
from palm.app.bootstrap import runtime_start_options
|
|
12
|
+
from palm.app.cli_settings import resolve_cli_settings
|
|
13
|
+
from palm.app.settings import PalmSettings
|
|
14
|
+
from palm.core.storage import StorageEngine
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def create_console() -> Any:
|
|
18
|
+
"""Build a Rich console for CLI output."""
|
|
19
|
+
try:
|
|
20
|
+
from rich.console import Console
|
|
21
|
+
|
|
22
|
+
return Console(highlight=False)
|
|
23
|
+
except ImportError as exc:
|
|
24
|
+
raise SystemExit(
|
|
25
|
+
"Rich is required for the Palm CLI. Install with: pip install palmengine[cli]"
|
|
26
|
+
) from exc
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def create_cli_app(
|
|
30
|
+
*,
|
|
31
|
+
storage_backend: str | None = None,
|
|
32
|
+
data_dir: Path | None = None,
|
|
33
|
+
storage: StorageEngine | None = None,
|
|
34
|
+
settings: PalmSettings | None = None,
|
|
35
|
+
) -> PalmApp:
|
|
36
|
+
"""
|
|
37
|
+
Construct a fully bootstrapped :class:`~palm.app.app.PalmApp` for the CLI.
|
|
38
|
+
|
|
39
|
+
Settings resolve from ``PALM_*`` environment variables, with optional CLI flag
|
|
40
|
+
overrides. ``bootstrap_cli`` wires the embedded runtime, ``InstanceManager``,
|
|
41
|
+
persistence hooks, and definition catalog — no manual runtime assembly.
|
|
42
|
+
|
|
43
|
+
Shared ``storage`` enables resume across separate CLI invocations (daemon +
|
|
44
|
+
terminal) when both use the same engine instance or durable backend + data dir.
|
|
45
|
+
"""
|
|
46
|
+
if settings is not None:
|
|
47
|
+
cfg = settings
|
|
48
|
+
if storage_backend is not None:
|
|
49
|
+
cfg = resolve_cli_settings(storage_backend=storage_backend, settings=cfg)
|
|
50
|
+
if data_dir is not None:
|
|
51
|
+
cfg = resolve_cli_settings(data_dir=data_dir, settings=cfg)
|
|
52
|
+
else:
|
|
53
|
+
shared_backend = (
|
|
54
|
+
storage.backend_name
|
|
55
|
+
if storage is not None and storage.is_initialized and storage.backend_name
|
|
56
|
+
else None
|
|
57
|
+
)
|
|
58
|
+
cfg = resolve_cli_settings(
|
|
59
|
+
storage_backend=storage_backend,
|
|
60
|
+
data_dir=data_dir,
|
|
61
|
+
align_shared_storage=shared_backend if storage_backend is None else None,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
app = PalmApp(cfg, storage=storage)
|
|
65
|
+
app.bootstrap()
|
|
66
|
+
app.bootstrap_cli(**runtime_start_options(cfg))
|
|
67
|
+
return app
|
palm/app/settings.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PalmSettings — central configuration for Palm applications.
|
|
3
|
+
|
|
4
|
+
Loaded from environment variables (``PALM_*``) and optional ``.env`` files via
|
|
5
|
+
``pydantic-settings``.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Literal
|
|
12
|
+
|
|
13
|
+
from pydantic import Field
|
|
14
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
15
|
+
|
|
16
|
+
SchedulerPolicy = Literal["inline", "queued"]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class PalmSettings(BaseSettings):
|
|
20
|
+
"""
|
|
21
|
+
Application-wide Palm configuration.
|
|
22
|
+
|
|
23
|
+
Environment prefix: ``PALM_`` (e.g. ``PALM_STORAGE_BACKEND=postgres``).
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
model_config = SettingsConfigDict(
|
|
27
|
+
env_prefix="PALM_",
|
|
28
|
+
env_file=".env",
|
|
29
|
+
env_file_encoding="utf-8",
|
|
30
|
+
extra="ignore",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
storage_backend: str = "memory"
|
|
34
|
+
data_dir: Path | None = None
|
|
35
|
+
observability: bool = False
|
|
36
|
+
auth_enforce: bool = False
|
|
37
|
+
auth_roles: list[str] = Field(default_factory=lambda: ["user"])
|
|
38
|
+
load_example_definitions: bool = True
|
|
39
|
+
default_scheduler: SchedulerPolicy = "inline"
|
|
40
|
+
max_concurrent_jobs: int | None = None
|
|
41
|
+
enable_state_snapshot: bool = False
|
|
42
|
+
snapshot_on_status: list[str] = Field(
|
|
43
|
+
default_factory=lambda: ["WAITING_FOR_INPUT", "SUCCEEDED", "FAILED"]
|
|
44
|
+
)
|
|
45
|
+
max_snapshots_per_instance: int = 10
|
|
46
|
+
max_loaded_instances: int = 128
|
|
47
|
+
max_concurrent_active: int = 32
|
|
48
|
+
reconcile_instances_on_startup: bool = True
|
|
49
|
+
|
|
50
|
+
def definition_roots(self) -> list[Path]:
|
|
51
|
+
"""Directories scanned for ``register_definitions`` modules."""
|
|
52
|
+
roots: list[Path] = []
|
|
53
|
+
if self.data_dir is not None:
|
|
54
|
+
roots.append(self.data_dir / "definitions")
|
|
55
|
+
roots.extend(
|
|
56
|
+
[
|
|
57
|
+
Path.cwd() / "examples" / "definitions",
|
|
58
|
+
]
|
|
59
|
+
)
|
|
60
|
+
return roots
|
|
61
|
+
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""
|
|
2
|
+
BehaviorTreeRunner — runs ``BasePattern`` executables against job state.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from palm.core.behavior_tree import BasePattern, PatternStatus
|
|
8
|
+
from palm.core.orchestration.execution.base_runner import JobRunner
|
|
9
|
+
from palm.core.orchestration.execution_context import ExecutionContext
|
|
10
|
+
from palm.core.orchestration.job import JobStatus
|
|
11
|
+
from palm.core.orchestration.run_result import RunResult
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BehaviorTreeRunner(JobRunner):
|
|
15
|
+
"""Advances a ``BasePattern`` stored in ``job.executable`` using ``job.state``."""
|
|
16
|
+
|
|
17
|
+
def run(self, ctx: ExecutionContext, *, budget: int | None = None) -> RunResult:
|
|
18
|
+
job = ctx.job
|
|
19
|
+
if job.is_terminal:
|
|
20
|
+
return RunResult(status=job.status, result=job.result)
|
|
21
|
+
|
|
22
|
+
pattern = job.executable
|
|
23
|
+
if not isinstance(pattern, BasePattern):
|
|
24
|
+
return RunResult(
|
|
25
|
+
status=JobStatus.FAILED,
|
|
26
|
+
error=TypeError("BehaviorTreeRunner requires a BasePattern executable"),
|
|
27
|
+
propagate=True,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
ticks = budget if budget is not None else 10_000
|
|
31
|
+
if ticks < 1:
|
|
32
|
+
raise ValueError("budget must be >= 1")
|
|
33
|
+
|
|
34
|
+
logical_status = job.status
|
|
35
|
+
if logical_status == JobStatus.PENDING:
|
|
36
|
+
logical_status = JobStatus.RUNNING
|
|
37
|
+
|
|
38
|
+
for _ in range(ticks):
|
|
39
|
+
try:
|
|
40
|
+
status = pattern.tick(job.state)
|
|
41
|
+
except Exception as exc:
|
|
42
|
+
return RunResult(status=JobStatus.FAILED, error=exc, propagate=True)
|
|
43
|
+
|
|
44
|
+
if status == PatternStatus.WAITING_FOR_INPUT:
|
|
45
|
+
return RunResult(status=JobStatus.WAITING_FOR_INPUT)
|
|
46
|
+
|
|
47
|
+
if status == PatternStatus.SUCCESS:
|
|
48
|
+
return RunResult(
|
|
49
|
+
status=JobStatus.SUCCEEDED,
|
|
50
|
+
result=job.state.get("__result__"),
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
if status == PatternStatus.FAILURE:
|
|
54
|
+
err = job.state.get("__error__")
|
|
55
|
+
return RunResult(
|
|
56
|
+
status=JobStatus.FAILED,
|
|
57
|
+
error=err if isinstance(err, BaseException) else RuntimeError("pattern failed"),
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
logical_status = JobStatus.RUNNING
|
|
61
|
+
|
|
62
|
+
if logical_status == JobStatus.RUNNING:
|
|
63
|
+
return RunResult(status=JobStatus.RUNNING)
|
|
64
|
+
|
|
65
|
+
return RunResult(
|
|
66
|
+
status=JobStatus.FAILED,
|
|
67
|
+
error=RuntimeError("pattern did not reach a terminal status"),
|
|
68
|
+
)
|
palm/common/__init__.py
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Shared coordination logic for Palm (non-plugin, non-core).
|
|
3
|
+
|
|
4
|
+
``palm.common`` holds definition-driven submission, plan staging, persistence
|
|
5
|
+
helpers, orchestration hooks, and pattern materialization — the glue between
|
|
6
|
+
``palm.core`` engines, ``palm.definitions``, and extensible ``palm.patterns``.
|
|
7
|
+
|
|
8
|
+
Extensible plugins live elsewhere:
|
|
9
|
+
|
|
10
|
+
- ``palm.patterns`` — register via ``pattern_registry``
|
|
11
|
+
- ``palm.providers`` — register via ``provider_registry``
|
|
12
|
+
- ``palm.storages`` — register via ``storage_registry``
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from typing import TYPE_CHECKING
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from palm.common.executions.executor import DefinitionExecutor
|
|
21
|
+
from palm.common.executions.flow_submission import FlowSubmission
|
|
22
|
+
from palm.common.hooks.instance_persistence import InstancePersistenceHook
|
|
23
|
+
from palm.common.patterns.build_context import PatternBuildContext
|
|
24
|
+
from palm.common.persistence.definition_repository import DefinitionRepository
|
|
25
|
+
from palm.common.persistence.instance_repository import InstanceRepository
|
|
26
|
+
from palm.common.plans.execution_plan import ExecutionPlan
|
|
27
|
+
from palm.common.plans.process_plan import ProcessPlan
|
|
28
|
+
from palm.common.plans.registry import PlanRegistry, StoredPlan
|
|
29
|
+
from palm.instances import ProcessInstance, StatusHistoryEntry
|
|
30
|
+
|
|
31
|
+
__all__ = [
|
|
32
|
+
"DefinitionBuildError",
|
|
33
|
+
"DefinitionExecutor",
|
|
34
|
+
"DefinitionNotFoundError",
|
|
35
|
+
"DefinitionRepository",
|
|
36
|
+
"ExecutionError",
|
|
37
|
+
"ExecutionPlan",
|
|
38
|
+
"FlowSubmission",
|
|
39
|
+
"InstanceNotFoundError",
|
|
40
|
+
"InstancePersistenceHook",
|
|
41
|
+
"InstanceRepository",
|
|
42
|
+
"InstanceResumeError",
|
|
43
|
+
"PatternBuildContext",
|
|
44
|
+
"PlanNotFoundError",
|
|
45
|
+
"PlanRegistry",
|
|
46
|
+
"PlanValidationError",
|
|
47
|
+
"ProcessInstance",
|
|
48
|
+
"ProcessPlan",
|
|
49
|
+
"StatusHistoryEntry",
|
|
50
|
+
"StoredPlan",
|
|
51
|
+
"build_pattern",
|
|
52
|
+
"prepare_flow_submission",
|
|
53
|
+
"prepare_process_plans",
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
_LAZY_EXPORTS: dict[str, tuple[str, str]] = {
|
|
57
|
+
"DefinitionBuildError": ("palm.common.exceptions", "DefinitionBuildError"),
|
|
58
|
+
"DefinitionNotFoundError": ("palm.common.exceptions", "DefinitionNotFoundError"),
|
|
59
|
+
"ExecutionError": ("palm.common.exceptions", "ExecutionError"),
|
|
60
|
+
"InstanceNotFoundError": ("palm.common.exceptions", "InstanceNotFoundError"),
|
|
61
|
+
"InstanceResumeError": ("palm.common.exceptions", "InstanceResumeError"),
|
|
62
|
+
"PlanNotFoundError": ("palm.common.exceptions", "PlanNotFoundError"),
|
|
63
|
+
"PlanValidationError": ("palm.common.exceptions", "PlanValidationError"),
|
|
64
|
+
"DefinitionExecutor": ("palm.common.executions.executor", "DefinitionExecutor"),
|
|
65
|
+
"FlowSubmission": ("palm.common.executions.flow_submission", "FlowSubmission"),
|
|
66
|
+
"prepare_flow_submission": ("palm.common.executions.flow_submission", "prepare_flow_submission"),
|
|
67
|
+
"prepare_process_plans": ("palm.common.executions.process_submission", "prepare_process_plans"),
|
|
68
|
+
"InstancePersistenceHook": ("palm.common.hooks.instance_persistence", "InstancePersistenceHook"),
|
|
69
|
+
"PatternBuildContext": ("palm.common.patterns.build_context", "PatternBuildContext"),
|
|
70
|
+
"build_pattern": ("palm.common.patterns.builder", "build_pattern"),
|
|
71
|
+
"DefinitionRepository": ("palm.common.persistence.definition_repository", "DefinitionRepository"),
|
|
72
|
+
"InstanceRepository": ("palm.common.persistence.instance_repository", "InstanceRepository"),
|
|
73
|
+
"ExecutionPlan": ("palm.common.plans.execution_plan", "ExecutionPlan"),
|
|
74
|
+
"ProcessPlan": ("palm.common.plans.process_plan", "ProcessPlan"),
|
|
75
|
+
"PlanRegistry": ("palm.common.plans.registry", "PlanRegistry"),
|
|
76
|
+
"StoredPlan": ("palm.common.plans.registry", "StoredPlan"),
|
|
77
|
+
"ProcessInstance": ("palm.instances", "ProcessInstance"),
|
|
78
|
+
"StatusHistoryEntry": ("palm.instances", "StatusHistoryEntry"),
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def __getattr__(name: str):
|
|
83
|
+
if name not in _LAZY_EXPORTS:
|
|
84
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
85
|
+
module_path, attr = _LAZY_EXPORTS[name]
|
|
86
|
+
import importlib
|
|
87
|
+
|
|
88
|
+
module = importlib.import_module(module_path)
|
|
89
|
+
value = getattr(module, attr)
|
|
90
|
+
globals()[name] = value
|
|
91
|
+
return value
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Execution-layer exceptions (outside core).
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ExecutionError(Exception):
|
|
9
|
+
"""Base error for definition-driven execution."""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class DefinitionBuildError(ExecutionError):
|
|
13
|
+
"""Raised when a flow or process definition cannot be built."""
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class DefinitionNotFoundError(ExecutionError):
|
|
17
|
+
"""Raised when a definition name or id cannot be resolved."""
|
|
18
|
+
|
|
19
|
+
def __init__(self, kind: str, ref: str) -> None:
|
|
20
|
+
super().__init__(f"{kind} definition not found: {ref!r}")
|
|
21
|
+
self.kind = kind
|
|
22
|
+
self.ref = ref
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class InstanceNotFoundError(ExecutionError):
|
|
26
|
+
"""Raised when a process instance id cannot be loaded."""
|
|
27
|
+
|
|
28
|
+
def __init__(self, instance_id: str) -> None:
|
|
29
|
+
super().__init__(f"Process instance not found: {instance_id!r}")
|
|
30
|
+
self.instance_id = instance_id
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class InstanceResumeError(ExecutionError):
|
|
34
|
+
"""Raised when an instance cannot be resumed (terminal, missing flow, etc.)."""
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class InstanceActiveLimitError(ExecutionError):
|
|
38
|
+
"""Raised when the active instance limit is exceeded."""
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class PlanValidationError(ExecutionError):
|
|
42
|
+
"""Raised when an :class:`~palm.common.plans.execution_plan.ExecutionPlan` fails pre-submit checks."""
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class PlanNotFoundError(ExecutionError):
|
|
46
|
+
"""Raised when a stored plan id cannot be resolved."""
|
|
47
|
+
|
|
48
|
+
def __init__(self, plan_id: str) -> None:
|
|
49
|
+
super().__init__(f"Execution plan not found: {plan_id!r}")
|
|
50
|
+
self.plan_id = plan_id
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Definition-driven submission — prepare and submit orchestration jobs."""
|
|
2
|
+
|
|
3
|
+
from palm.common.executions.executor import DefinitionExecutor
|
|
4
|
+
from palm.common.executions.flow_submission import FlowSubmission, prepare_flow_submission
|
|
5
|
+
from palm.common.executions.process_submission import prepare_process_plans
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"DefinitionExecutor",
|
|
9
|
+
"FlowSubmission",
|
|
10
|
+
"prepare_flow_submission",
|
|
11
|
+
"prepare_process_plans",
|
|
12
|
+
]
|