grctl-sdk-python 0.1.2__py3-none-any.whl → 0.1.3__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.
- grctl/client/client.py +53 -35
- grctl/models/history.py +3 -0
- grctl/nats/history_fetch.py +30 -0
- grctl/nats/subscriber.py +2 -2
- grctl/worker/context.py +7 -2
- grctl/worker/worker.py +41 -21
- grctl/workflow/future.py +12 -1
- {grctl_sdk_python-0.1.2.dist-info → grctl_sdk_python-0.1.3.dist-info}/METADATA +13 -13
- {grctl_sdk_python-0.1.2.dist-info → grctl_sdk_python-0.1.3.dist-info}/RECORD +11 -11
- {grctl_sdk_python-0.1.2.dist-info → grctl_sdk_python-0.1.3.dist-info}/WHEEL +0 -0
- {grctl_sdk_python-0.1.2.dist-info → grctl_sdk_python-0.1.3.dist-info}/licenses/LICENSE +0 -0
grctl/client/client.py
CHANGED
|
@@ -11,10 +11,11 @@ from typing import Any
|
|
|
11
11
|
import msgspec
|
|
12
12
|
from ulid import ULID
|
|
13
13
|
|
|
14
|
-
from grctl.models import DescribeCmd, GrctlAPIResponse, RunInfo
|
|
14
|
+
from grctl.models import DescribeCmd, GrctlAPIResponse, HistoryEvent, RunInfo
|
|
15
15
|
from grctl.models.command import CmdKind, Command
|
|
16
16
|
from grctl.models.errors import WorkflowError, WorkflowNotFoundError
|
|
17
17
|
from grctl.nats.connection import Connection
|
|
18
|
+
from grctl.nats.history_fetch import fetch_run_history
|
|
18
19
|
from grctl.worker.codec import CodecRegistry
|
|
19
20
|
from grctl.workflow.handle import WorkflowHandle
|
|
20
21
|
|
|
@@ -30,36 +31,16 @@ class Client:
|
|
|
30
31
|
self._connection = connection
|
|
31
32
|
self._codec = codec or CodecRegistry()
|
|
32
33
|
|
|
33
|
-
async def
|
|
34
|
-
|
|
35
|
-
workflow_type: str,
|
|
36
|
-
workflow_id: str,
|
|
37
|
-
workflow_input: Any | None = None,
|
|
38
|
-
workflow_timeout: timedelta | None = None,
|
|
39
|
-
) -> Any:
|
|
40
|
-
"""Run a workflow and wait for its result."""
|
|
41
|
-
wf_handle = await self.start_workflow(
|
|
42
|
-
workflow_type=workflow_type,
|
|
43
|
-
workflow_id=workflow_id,
|
|
44
|
-
workflow_input=workflow_input,
|
|
45
|
-
workflow_timeout=workflow_timeout,
|
|
46
|
-
)
|
|
47
|
-
timeout = workflow_timeout.total_seconds() if workflow_timeout else None
|
|
48
|
-
try:
|
|
49
|
-
return await asyncio.wait_for(wf_handle.future, timeout=timeout)
|
|
50
|
-
finally:
|
|
51
|
-
await wf_handle.future.stop()
|
|
52
|
-
|
|
53
|
-
async def get_workflow_handle(self, workflow_id: str) -> WorkflowHandle:
|
|
54
|
-
"""Get a handle for an already-running workflow."""
|
|
34
|
+
async def describe(self, wf_id: str) -> RunInfo:
|
|
35
|
+
"""Describe the latest run for a workflow ID."""
|
|
55
36
|
cmd = Command(
|
|
56
37
|
id=str(ULID()),
|
|
57
38
|
kind=CmdKind.run_describe,
|
|
58
39
|
timestamp=datetime.now(UTC),
|
|
59
|
-
msg=DescribeCmd(wf_id=
|
|
40
|
+
msg=DescribeCmd(wf_id=wf_id),
|
|
60
41
|
)
|
|
61
42
|
# Use a routing-only RunInfo — publish_cmd only needs wf_id for subject routing.
|
|
62
|
-
routing_info = RunInfo(id="", wf_type="", wf_id=
|
|
43
|
+
routing_info = RunInfo(id="", wf_type="", wf_id=wf_id)
|
|
63
44
|
response_bytes = await self._connection.publisher.publish_cmd(routing_info, cmd)
|
|
64
45
|
|
|
65
46
|
response = msgspec.msgpack.decode(response_bytes, type=GrctlAPIResponse)
|
|
@@ -67,10 +48,34 @@ class Client:
|
|
|
67
48
|
error_msg = response.error.message if response.error else "unknown error"
|
|
68
49
|
error_code = response.error.code if response.error else 0
|
|
69
50
|
if error_code == ErrWorkflowRunNotFoundCode:
|
|
70
|
-
raise WorkflowNotFoundError(f"workflow '{
|
|
51
|
+
raise WorkflowNotFoundError(f"workflow '{wf_id}' not found: {error_msg}")
|
|
71
52
|
raise WorkflowError(f"describe failed (code={error_code}): {error_msg}")
|
|
72
53
|
|
|
73
|
-
|
|
54
|
+
return msgspec.msgpack.decode(response.payload, type=RunInfo)
|
|
55
|
+
|
|
56
|
+
async def run_workflow(
|
|
57
|
+
self,
|
|
58
|
+
type: str, # noqa: A002
|
|
59
|
+
id: str, # noqa: A002
|
|
60
|
+
input: Any | None = None, # noqa: A002
|
|
61
|
+
timeout: timedelta | None = None, # noqa: ASYNC109
|
|
62
|
+
) -> Any:
|
|
63
|
+
"""Run a workflow and wait for its result."""
|
|
64
|
+
wf_handle = await self.start_workflow(
|
|
65
|
+
type=type,
|
|
66
|
+
id=id,
|
|
67
|
+
input=input,
|
|
68
|
+
timeout=timeout,
|
|
69
|
+
)
|
|
70
|
+
wait_timeout = timeout.total_seconds() if timeout else None
|
|
71
|
+
try:
|
|
72
|
+
return await asyncio.wait_for(wf_handle.future, timeout=wait_timeout)
|
|
73
|
+
finally:
|
|
74
|
+
await wf_handle.future.stop()
|
|
75
|
+
|
|
76
|
+
async def get_workflow_handle(self, wfid: str) -> WorkflowHandle:
|
|
77
|
+
"""Get a handle for an already-running workflow."""
|
|
78
|
+
run_info = await self.describe(wfid)
|
|
74
79
|
|
|
75
80
|
handle = WorkflowHandle(
|
|
76
81
|
run_info=run_info,
|
|
@@ -81,27 +86,40 @@ class Client:
|
|
|
81
86
|
await handle.attach()
|
|
82
87
|
return handle
|
|
83
88
|
|
|
89
|
+
async def get_history(self, wf_id: str, run_id: str | None = None) -> list[HistoryEvent]:
|
|
90
|
+
"""Return the ordered history events for a workflow run."""
|
|
91
|
+
resolved_run_id = run_id
|
|
92
|
+
if resolved_run_id is None:
|
|
93
|
+
resolved_run_id = (await self.describe(wf_id)).id
|
|
94
|
+
|
|
95
|
+
return await fetch_run_history(
|
|
96
|
+
js=self._connection.js,
|
|
97
|
+
manifest=self._connection.manifest,
|
|
98
|
+
wf_id=wf_id,
|
|
99
|
+
run_id=resolved_run_id,
|
|
100
|
+
)
|
|
101
|
+
|
|
84
102
|
async def start_workflow(
|
|
85
103
|
self,
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
104
|
+
type: str, # noqa: A002
|
|
105
|
+
id: str, # noqa: A002
|
|
106
|
+
input: Any | None = None, # noqa: A002
|
|
107
|
+
timeout: timedelta | None = None, # noqa: ASYNC109
|
|
90
108
|
) -> WorkflowHandle:
|
|
91
109
|
"""Start a workflow and return a handle to track and interact with it."""
|
|
92
110
|
workflow_run_id = str(ULID())
|
|
93
111
|
|
|
94
112
|
run_info = RunInfo(
|
|
95
113
|
id=workflow_run_id,
|
|
96
|
-
wf_type=
|
|
97
|
-
wf_id=
|
|
98
|
-
timeout=int(
|
|
114
|
+
wf_type=type,
|
|
115
|
+
wf_id=id,
|
|
116
|
+
timeout=int(timeout.total_seconds()) if timeout else None,
|
|
99
117
|
created_at=datetime.now(UTC),
|
|
100
118
|
)
|
|
101
119
|
|
|
102
120
|
handle = WorkflowHandle(
|
|
103
121
|
run_info=run_info,
|
|
104
|
-
payload=
|
|
122
|
+
payload=input,
|
|
105
123
|
connection=self._connection,
|
|
106
124
|
codec=self._codec,
|
|
107
125
|
)
|
grctl/models/history.py
CHANGED
|
@@ -202,6 +202,7 @@ class ChildWorkflowStarted(msgspec.Struct):
|
|
|
202
202
|
run_id: str
|
|
203
203
|
wf_type: str
|
|
204
204
|
wf_id: str
|
|
205
|
+
input: Any | None = None
|
|
205
206
|
|
|
206
207
|
|
|
207
208
|
class ParentEventSent(msgspec.Struct):
|
|
@@ -209,6 +210,8 @@ class ParentEventSent(msgspec.Struct):
|
|
|
209
210
|
|
|
210
211
|
event_name: str
|
|
211
212
|
payload: Any
|
|
213
|
+
parent_wf_type: str
|
|
214
|
+
parent_wf_id: str
|
|
212
215
|
|
|
213
216
|
|
|
214
217
|
RunEvents = RunCancelScheduled | RunCancelled | RunCompleted | RunFailed | RunScheduled | RunStarted | RunTimeout
|
grctl/nats/history_fetch.py
CHANGED
|
@@ -9,6 +9,36 @@ _FETCH_BATCH_SIZE = 256
|
|
|
9
9
|
_FETCH_TIMEOUT_SECONDS = 0.25
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
async def fetch_run_history(
|
|
13
|
+
js: JetStreamContext,
|
|
14
|
+
manifest: NatsManifest,
|
|
15
|
+
wf_id: str,
|
|
16
|
+
run_id: str,
|
|
17
|
+
) -> list[HistoryEvent]:
|
|
18
|
+
history_subject = manifest.history_subject(wf_id=wf_id, run_id=run_id)
|
|
19
|
+
history_stream = manifest.history_stream_name()
|
|
20
|
+
subscription = await js.pull_subscribe(
|
|
21
|
+
subject=history_subject,
|
|
22
|
+
stream=history_stream,
|
|
23
|
+
config=ConsumerConfig(
|
|
24
|
+
deliver_policy=DeliverPolicy.ALL,
|
|
25
|
+
ack_policy=AckPolicy.NONE,
|
|
26
|
+
inactive_threshold=1.0,
|
|
27
|
+
),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
events: list[HistoryEvent] = []
|
|
31
|
+
try:
|
|
32
|
+
try:
|
|
33
|
+
while True:
|
|
34
|
+
messages = await subscription.fetch(batch=_FETCH_BATCH_SIZE, timeout=_FETCH_TIMEOUT_SECONDS)
|
|
35
|
+
events.extend(history_decoder(msg.data) for msg in messages if msg.data)
|
|
36
|
+
except (TimeoutError, FetchTimeoutError):
|
|
37
|
+
return events
|
|
38
|
+
finally:
|
|
39
|
+
await subscription.unsubscribe()
|
|
40
|
+
|
|
41
|
+
|
|
12
42
|
async def fetch_step_history(
|
|
13
43
|
js: JetStreamContext,
|
|
14
44
|
manifest: NatsManifest,
|
grctl/nats/subscriber.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import contextlib
|
|
3
3
|
import json
|
|
4
|
+
from typing import Any
|
|
4
5
|
|
|
5
6
|
import msgspec
|
|
6
7
|
from nats.aio.msg import Msg
|
|
@@ -11,7 +12,6 @@ from grctl.logging_config import get_logger
|
|
|
11
12
|
from grctl.models import directive_decoder
|
|
12
13
|
from grctl.nats.manifest import NatsManifest
|
|
13
14
|
from grctl.settings import get_settings
|
|
14
|
-
from grctl.worker.run_manager import RunManager
|
|
15
15
|
|
|
16
16
|
logger = get_logger(__name__)
|
|
17
17
|
|
|
@@ -24,7 +24,7 @@ class Subscriber:
|
|
|
24
24
|
js: JetStreamContext,
|
|
25
25
|
manifest: NatsManifest,
|
|
26
26
|
wf_types: list[str],
|
|
27
|
-
run_manager:
|
|
27
|
+
run_manager: Any,
|
|
28
28
|
) -> None:
|
|
29
29
|
self._js = js
|
|
30
30
|
self._manifest = manifest
|
grctl/worker/context.py
CHANGED
|
@@ -198,7 +198,12 @@ class Context:
|
|
|
198
198
|
)
|
|
199
199
|
await runtime.record(
|
|
200
200
|
HistoryKind.parent_event_sent,
|
|
201
|
-
ParentEventSent(
|
|
201
|
+
ParentEventSent(
|
|
202
|
+
event_name=event_name,
|
|
203
|
+
payload=payload,
|
|
204
|
+
parent_wf_type=self._parent_run.wf_type,
|
|
205
|
+
parent_wf_id=self._parent_run.wf_id,
|
|
206
|
+
),
|
|
202
207
|
operation_id,
|
|
203
208
|
)
|
|
204
209
|
|
|
@@ -244,7 +249,7 @@ class Context:
|
|
|
244
249
|
await handle.start()
|
|
245
250
|
await runtime.record(
|
|
246
251
|
HistoryKind.child_started,
|
|
247
|
-
ChildWorkflowStarted(run_id=run_id, wf_type=workflow_type, wf_id=workflow_id),
|
|
252
|
+
ChildWorkflowStarted(run_id=run_id, wf_type=workflow_type, wf_id=workflow_id, input=workflow_input),
|
|
248
253
|
operation_id,
|
|
249
254
|
)
|
|
250
255
|
return handle
|
grctl/worker/worker.py
CHANGED
|
@@ -19,6 +19,7 @@ from grctl.workflow.workflow import Workflow
|
|
|
19
19
|
|
|
20
20
|
logger = get_logger(__name__)
|
|
21
21
|
|
|
22
|
+
|
|
22
23
|
# Constants
|
|
23
24
|
DEFAULT_WORKFLOW_TIMEOUT_SECONDS: float = 30.0
|
|
24
25
|
WORKER_HEARTBEAT_INTERVAL_SECONDS: int = 1
|
|
@@ -54,8 +55,10 @@ class Worker:
|
|
|
54
55
|
self._connection = connection
|
|
55
56
|
self._workflow_logger = workflow_logger
|
|
56
57
|
self._stop_event = asyncio.Event()
|
|
58
|
+
self._startup_event = asyncio.Event()
|
|
57
59
|
self._subscriber: Subscriber | None = None
|
|
58
60
|
self._run_manager: RunManager | None = None
|
|
61
|
+
self._startup_error: Exception | None = None
|
|
59
62
|
|
|
60
63
|
@cached_property
|
|
61
64
|
def worker_name(self) -> str:
|
|
@@ -81,31 +84,48 @@ class Worker:
|
|
|
81
84
|
|
|
82
85
|
Creates RunManager for workflow execution and subscribes to workflow subjects.
|
|
83
86
|
"""
|
|
87
|
+
self._startup_event.clear()
|
|
88
|
+
self._startup_error = None
|
|
89
|
+
|
|
84
90
|
logger.info(
|
|
85
91
|
f"Starting worker with {len(self._workflows)} registered workflows",
|
|
86
92
|
)
|
|
87
93
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
94
|
+
try:
|
|
95
|
+
self._run_manager = RunManager(
|
|
96
|
+
worker_name=self.worker_name,
|
|
97
|
+
worker_id=self.worker_id,
|
|
98
|
+
workflows=self._workflows,
|
|
99
|
+
connection=self._connection,
|
|
100
|
+
workflow_logger=self._workflow_logger,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
wf_types = [wf.workflow_type for wf in self._workflows]
|
|
104
|
+
self._subscriber = Subscriber(
|
|
105
|
+
js=self._connection.js,
|
|
106
|
+
manifest=self._connection.manifest,
|
|
107
|
+
wf_types=wf_types,
|
|
108
|
+
run_manager=self._run_manager,
|
|
109
|
+
)
|
|
110
|
+
await self._subscriber.start()
|
|
111
|
+
self._startup_event.set()
|
|
112
|
+
|
|
113
|
+
logger.info(f"Worker {self.worker_name} ({self.worker_id}) started and ready to process messages")
|
|
114
|
+
|
|
115
|
+
# Keep worker alive
|
|
116
|
+
await self._process_messages()
|
|
117
|
+
except Exception as exc:
|
|
118
|
+
self._startup_error = exc
|
|
119
|
+
self._startup_event.set()
|
|
120
|
+
raise
|
|
121
|
+
|
|
122
|
+
async def wait_until_ready(self, timeout_ms: float = 5.0) -> None:
|
|
123
|
+
"""Wait until worker startup succeeds or fails."""
|
|
124
|
+
await asyncio.wait_for(self._startup_event.wait(), timeout=timeout_ms)
|
|
125
|
+
if self._startup_error is not None:
|
|
126
|
+
raise self._startup_error
|
|
127
|
+
if self._subscriber is None:
|
|
128
|
+
raise RuntimeError("Worker startup completed without creating a subscriber")
|
|
109
129
|
|
|
110
130
|
async def _process_messages(self) -> None:
|
|
111
131
|
"""Keep worker alive to process commands."""
|
grctl/workflow/future.py
CHANGED
|
@@ -41,6 +41,8 @@ class WorkflowFuture(asyncio.Future[Any]):
|
|
|
41
41
|
run_id=run_info.id,
|
|
42
42
|
handler=self._handle_history_event,
|
|
43
43
|
)
|
|
44
|
+
self._subscriber_stopped = False
|
|
45
|
+
self.add_done_callback(self._schedule_subscriber_stop)
|
|
44
46
|
self._history_update_handlers: dict[HistoryKind, Callable[[HistoryEvent], None]] = {
|
|
45
47
|
HistoryKind.run_scheduled: self._on_non_terminal_event,
|
|
46
48
|
HistoryKind.run_started: self._on_non_terminal_event,
|
|
@@ -54,9 +56,18 @@ class WorkflowFuture(asyncio.Future[Any]):
|
|
|
54
56
|
"""Start listening for events and publish run command."""
|
|
55
57
|
await self._subscriber.start()
|
|
56
58
|
|
|
59
|
+
def _schedule_subscriber_stop(self, _: asyncio.Future) -> None:
|
|
60
|
+
# done_callback must be sync, so we schedule the async stop as a task.
|
|
61
|
+
if self._subscriber_stopped:
|
|
62
|
+
return
|
|
63
|
+
self._subscriber_stopped = True
|
|
64
|
+
asyncio.ensure_future(self._subscriber.stop()) # noqa: RUF006
|
|
65
|
+
|
|
57
66
|
async def stop(self) -> None:
|
|
58
67
|
"""Stop listening for events and cleanup."""
|
|
59
|
-
|
|
68
|
+
if not self._subscriber_stopped:
|
|
69
|
+
self._subscriber_stopped = True
|
|
70
|
+
await self._subscriber.stop()
|
|
60
71
|
|
|
61
72
|
if not self.done():
|
|
62
73
|
self.cancel()
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: grctl-sdk-python
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: The Python SDK for the Ground Control
|
|
5
|
-
Author:
|
|
6
|
-
Author-email:
|
|
5
|
+
Author: Cem Evren Ates
|
|
6
|
+
Author-email: Cem Evren Ates <cemevre@gmail.com>
|
|
7
7
|
License-Expression: Apache-2.0
|
|
8
8
|
License-File: LICENSE
|
|
9
9
|
Classifier: Development Status :: 3 - Alpha
|
|
@@ -25,18 +25,18 @@ Requires-Dist: pydantic-settings>=2.11.0
|
|
|
25
25
|
Requires-Dist: pyyaml>=6.0.3
|
|
26
26
|
Requires-Dist: pydantic>=2.12.5
|
|
27
27
|
Requires-Python: >=3.13
|
|
28
|
-
Project-URL: Homepage, https://github.com/
|
|
29
|
-
Project-URL: Documentation, https://
|
|
30
|
-
Project-URL: Repository, https://github.com/
|
|
31
|
-
Project-URL: Issues, https://github.com/
|
|
32
|
-
Project-URL: Changelog, https://github.com/
|
|
28
|
+
Project-URL: Homepage, https://github.com/grctl/sdk-python
|
|
29
|
+
Project-URL: Documentation, https://grctl.github.io/grctl/
|
|
30
|
+
Project-URL: Repository, https://github.com/grctl/sdk-python
|
|
31
|
+
Project-URL: Issues, https://github.com/grctl/sdk-python/issues
|
|
32
|
+
Project-URL: Changelog, https://github.com/grctl/sdk-python/blob/main/CHANGELOG.md
|
|
33
33
|
Description-Content-Type: text/markdown
|
|
34
34
|
|
|
35
35
|
# Ground Control Python SDK
|
|
36
36
|
|
|
37
|
-
The official Python SDK for [Ground Control](https://github.com/
|
|
37
|
+
The official Python SDK for [Ground Control](https://github.com/grctl/grctl) — a lightweight workflow orchestration engine built for fail-safe execution.
|
|
38
38
|
|
|
39
|
-
**[Documentation](https://
|
|
39
|
+
**[Documentation](https://grctl.github.io/grctl/)**
|
|
40
40
|
|
|
41
41
|
> [!WARNING]
|
|
42
42
|
> **Status: Pre-alpha**
|
|
@@ -55,12 +55,12 @@ pip install grctl-sdk-python
|
|
|
55
55
|
|
|
56
56
|
## Contributing
|
|
57
57
|
|
|
58
|
-
Contributions are welcome! Please read our [Contributing Guide](https://github.com/
|
|
58
|
+
Contributions are welcome! Please read our [Contributing Guide](https://github.com/grctl/grctl/blob/main/CONTRIBUTING.md) for more information.
|
|
59
59
|
|
|
60
60
|
## Security
|
|
61
61
|
|
|
62
|
-
Please see our [Security Policy](https://github.com/
|
|
62
|
+
Please see our [Security Policy](https://github.com/grctl/grctl/blob/main/SECURITY.md) for reporting vulnerabilities.
|
|
63
63
|
|
|
64
64
|
## License
|
|
65
65
|
|
|
66
|
-
This project is licensed under the Apache License 2.0 - see the [LICENSE](https://github.com/
|
|
66
|
+
This project is licensed under the Apache License 2.0 - see the [LICENSE](https://github.com/grctl/grctl/blob/main/LICENSE) file for details.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
grctl/__init__.py,sha256=ovSyTyP0DJxBW_jC8CJrwYUs_BfXtMTnJqJ9qScZZyY,41
|
|
2
2
|
grctl/client/__init__.py,sha256=FxY4a__J1SciqPTtouzQP8e76yRInchtrv_5OT9XoXc,259
|
|
3
|
-
grctl/client/client.py,sha256=
|
|
3
|
+
grctl/client/client.py,sha256=0ozm-sRz0kiV0U1VWJjNTCnd14uQJ4U_3Uk66JxGLZw,4510
|
|
4
4
|
grctl/logging_config.py,sha256=OMoz3FRnxAwkE9BNDuFxFu8aRzURnXeU9-75xVXiomg,1457
|
|
5
5
|
grctl/models/__init__.py,sha256=-E1nliiY_Esiz-8Pc3WkyT7eYoph0czLsl3Uz8n6P4w,2752
|
|
6
6
|
grctl/models/api.py,sha256=xygDA8b0E5BeQSrtfu_RToTW7XB2XWEO3n-zbh4W4S8,288
|
|
@@ -8,25 +8,25 @@ grctl/models/command.py,sha256=SgnaAt2JNQOventxDU5C99-BAOB3WFhQADNsNfVhY54,2509
|
|
|
8
8
|
grctl/models/common.py,sha256=XtqhHrgwIRlQGTEjrnsAfIPqajEpg9-4MkeSk87eemE,174
|
|
9
9
|
grctl/models/directive.py,sha256=9N_v4YvI4Qew-_O4UHeBnQJ2HrDSkqo9uCflrCFltbY,4947
|
|
10
10
|
grctl/models/errors.py,sha256=ckFlCRgmiYYWXqi22pY9cOIGRCgGXiG4FknhxjD4oqU,179
|
|
11
|
-
grctl/models/history.py,sha256=
|
|
11
|
+
grctl/models/history.py,sha256=O_DNZcKG70b169dxBFH3HFw8vTKj9BtKeLGHkQDBoO4,8121
|
|
12
12
|
grctl/models/run_info.py,sha256=OFbZ6ms_G4fpNTuScm03VbaYHpmQUwRzofvIIre3Eu8,2134
|
|
13
13
|
grctl/models/run_info_helper.py,sha256=WG_lydSwkwX8PFxWZ9vMZw18cwFyQks-50x8-vMOlcE,301
|
|
14
14
|
grctl/models/worker.py,sha256=Av8HQoTkkPUjV0ztq_NckC-Rem57g4ssTFyu8JrqsQo,1889
|
|
15
15
|
grctl/nats/__init__.py,sha256=QTrNaWbv4WV1gLKcQlbPufZYDNCkww42edwxBoHVE-8,37
|
|
16
16
|
grctl/nats/connection.py,sha256=DIQ7jz0XXRGlTeuuvV-cq4iNDj06V397vGo44Pnyqdg,1878
|
|
17
|
-
grctl/nats/history_fetch.py,sha256=
|
|
17
|
+
grctl/nats/history_fetch.py,sha256=UuCWSe9jPP0Ry8HDePN_VOx0B07JNMxQmKpuxSxNTKY,2398
|
|
18
18
|
grctl/nats/history_sub.py,sha256=E-t5loBTYNU5OH_8Xr4WFGFo3jrU9URbvBc-TxGSmxw,2198
|
|
19
19
|
grctl/nats/kv_store.py,sha256=fYoigg3_GHryYrphf9OoA-3uyffPr-YDz4Dt5G1u5OQ,1307
|
|
20
20
|
grctl/nats/manifest.py,sha256=NMxeuw5_j8WKqGdOp3DInGBLrYriye9RD3y4Ymr0mW8,9222
|
|
21
21
|
grctl/nats/nats_client.py,sha256=3XK8K3_ix-3vcGnMXo_LAY2fn-14y8JVSjbFCF_6OC4,343
|
|
22
22
|
grctl/nats/nats_manifest.yaml,sha256=FZXsJY3wqSNp3mhzh2awA_7NDq8OV8Mz0b2VK03T_dM,2661
|
|
23
23
|
grctl/nats/publisher.py,sha256=-PCkfd4OIyjHa645oLuAGQyL3dy2bw0serMtmyF4f1o,1561
|
|
24
|
-
grctl/nats/subscriber.py,sha256=
|
|
24
|
+
grctl/nats/subscriber.py,sha256=0LG1CkR--fxPe5PuFTuFNEA1UoXupRvqvek2T0fpUQA,4436
|
|
25
25
|
grctl/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
26
26
|
grctl/settings.py,sha256=8O88vPcVzLHHv8JVxgNbwE3ErDqxjZf2_N4Tj35t7HM,601
|
|
27
27
|
grctl/worker/__init__.py,sha256=dEnavSsxpbvAFonVcZiS-VPxtvgRneAp86XtuXqabiw,256
|
|
28
28
|
grctl/worker/codec.py,sha256=ywioAv30GKxxAcAAbX7a3unFWpz9OBuzNXzy90i9iyw,1642
|
|
29
|
-
grctl/worker/context.py,sha256=
|
|
29
|
+
grctl/worker/context.py,sha256=IzKZFS0LBQVTwgkiRaGwhUdCZs_YQrcFW3sqz_oqfZs,10439
|
|
30
30
|
grctl/worker/errors.py,sha256=QFFruX23v1r-Xnc6gihRfLaapnUSY9HMBPWq5lwjB_U,1239
|
|
31
31
|
grctl/worker/logger.py,sha256=vjHxk03ro1rVvDP2l94lfg-2yeN_pUks4tbrEm52YyQ,1364
|
|
32
32
|
grctl/worker/run_manager.py,sha256=F1jdGrt8KS7WoLIacz6uQizfhTLpGP-21NLCgN3P4sA,4751
|
|
@@ -34,12 +34,12 @@ grctl/worker/runner.py,sha256=icz-Q9SY3u4bma1iwzUaq6ifAo0E1QrWYBJknI495Ec,6866
|
|
|
34
34
|
grctl/worker/runtime.py,sha256=MfuYfsV0aEhLmRqrPl4vdnOvLDsWhPpWnfp-nFEqgoY,6783
|
|
35
35
|
grctl/worker/store.py,sha256=puLSeVV4RfWibELGsjdiztZcPBRRlIV1iupAaUr0JYs,1750
|
|
36
36
|
grctl/worker/task.py,sha256=3FFbMiLdBTXAV2L6DI3kRfqYxXxu-0_mLUvieovh0TU,14487
|
|
37
|
-
grctl/worker/worker.py,sha256=
|
|
37
|
+
grctl/worker/worker.py,sha256=RfA2_TdRDEjoTU7Q_5sTnaxgnoZVIiY6wa3G1UiF5RA,6137
|
|
38
38
|
grctl/workflow/__init__.py,sha256=vu0cIFdbSgH6PSU60keXN2jkkkGn4bSG3UyRpIsSJXU,287
|
|
39
|
-
grctl/workflow/future.py,sha256=
|
|
39
|
+
grctl/workflow/future.py,sha256=oIzTArOYTwTpzVZBxxBxBeSNvswVhqE6CvJhd_-ljKE,5585
|
|
40
40
|
grctl/workflow/handle.py,sha256=3dRhwLHRSfO7-wvka3YL_JEkUJLvy2Lnr1dMXWwAsuE,2671
|
|
41
41
|
grctl/workflow/workflow.py,sha256=jBdDBGjg6gE0t02CTN1-pBLk2DpMGEsk63TAuQXj7tQ,8602
|
|
42
|
-
grctl_sdk_python-0.1.
|
|
43
|
-
grctl_sdk_python-0.1.
|
|
44
|
-
grctl_sdk_python-0.1.
|
|
45
|
-
grctl_sdk_python-0.1.
|
|
42
|
+
grctl_sdk_python-0.1.3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
43
|
+
grctl_sdk_python-0.1.3.dist-info/WHEEL,sha256=q5IF0q2xCp3ktUFRCVWsQLjl2ChNlWXBJtnI1LCGdJ8,80
|
|
44
|
+
grctl_sdk_python-0.1.3.dist-info/METADATA,sha256=tK61B6ZhJKVHMZURivXut8gXVajyAj7iFaeOMsk5m9g,2309
|
|
45
|
+
grctl_sdk_python-0.1.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|