dirigent-cli 0.20.0__tar.gz → 0.21.0__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.
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/PKG-INFO +9 -9
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/pyproject.toml +9 -9
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/pyproject.toml.orig +9 -9
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/commands.py +3 -1
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/local.py +4 -3
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/main.py +3 -2
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/seeding.py +2 -1
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/triggers.py +70 -3
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/LICENSE +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/README.md +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/__init__.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/aliases.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/context.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/explain.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/formatters.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/graph.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/health.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/init_form.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/messages.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/output.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/params.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/profiles.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/project.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/py.typed +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/reaper.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/scaffold.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/schemas.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/sources.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/starters.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/stream.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/summaries.py +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/templates/pack/README.md.tmpl +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/templates/pack/__init__.py.tmpl +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/templates/pack/operator.py.tmpl +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/templates/pack/pyproject.toml.tmpl +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/templates/pack/test_plugin.py.tmpl +0 -0
- {dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/timing.py +0 -0
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dirigent-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.21.0
|
|
4
4
|
Summary: The dirigent command line interface (dirigent / dg).
|
|
5
5
|
License-Expression: LicenseRef-Proprietary
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Classifier: Programming Language :: Python :: 3
|
|
8
8
|
Classifier: Programming Language :: Python :: 3.13
|
|
9
|
-
Requires-Dist: dirigent-block-execute==0.
|
|
10
|
-
Requires-Dist: dirigent-blocks==0.
|
|
11
|
-
Requires-Dist: dirigent-client==0.
|
|
12
|
-
Requires-Dist: dirigent-common==0.
|
|
13
|
-
Requires-Dist: dirigent-core==0.
|
|
14
|
-
Requires-Dist: dirigent-examples==0.
|
|
15
|
-
Requires-Dist: dirigent-plugin==0.
|
|
16
|
-
Requires-Dist: dirigent-server==0.
|
|
9
|
+
Requires-Dist: dirigent-block-execute==0.21.0
|
|
10
|
+
Requires-Dist: dirigent-blocks==0.21.0
|
|
11
|
+
Requires-Dist: dirigent-client==0.21.0
|
|
12
|
+
Requires-Dist: dirigent-common==0.21.0
|
|
13
|
+
Requires-Dist: dirigent-core==0.21.0
|
|
14
|
+
Requires-Dist: dirigent-examples==0.21.0
|
|
15
|
+
Requires-Dist: dirigent-plugin==0.21.0
|
|
16
|
+
Requires-Dist: dirigent-server==0.21.0
|
|
17
17
|
Requires-Dist: httpx2>=2.12.0
|
|
18
18
|
Requires-Dist: python-dotenv>=1.1.0
|
|
19
19
|
Requires-Dist: pyyaml>=6.0.3
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "dirigent-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.21.0"
|
|
4
4
|
description = "The dirigent command line interface (dirigent / dg)."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.13"
|
|
@@ -11,14 +11,14 @@ classifiers = [
|
|
|
11
11
|
"Programming Language :: Python :: 3.13",
|
|
12
12
|
]
|
|
13
13
|
dependencies = [
|
|
14
|
-
"dirigent-block-execute==0.
|
|
15
|
-
"dirigent-blocks==0.
|
|
16
|
-
"dirigent-client==0.
|
|
17
|
-
"dirigent-common==0.
|
|
18
|
-
"dirigent-core==0.
|
|
19
|
-
"dirigent-examples==0.
|
|
20
|
-
"dirigent-plugin==0.
|
|
21
|
-
"dirigent-server==0.
|
|
14
|
+
"dirigent-block-execute==0.21.0",
|
|
15
|
+
"dirigent-blocks==0.21.0",
|
|
16
|
+
"dirigent-client==0.21.0",
|
|
17
|
+
"dirigent-common==0.21.0",
|
|
18
|
+
"dirigent-core==0.21.0",
|
|
19
|
+
"dirigent-examples==0.21.0",
|
|
20
|
+
"dirigent-plugin==0.21.0",
|
|
21
|
+
"dirigent-server==0.21.0",
|
|
22
22
|
"httpx2>=2.12.0",
|
|
23
23
|
"python-dotenv>=1.1.0",
|
|
24
24
|
"pyyaml>=6.0.3",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "dirigent-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.21.0"
|
|
4
4
|
description = "The dirigent command line interface (dirigent / dg)."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.13"
|
|
@@ -11,14 +11,14 @@ classifiers = [
|
|
|
11
11
|
"Programming Language :: Python :: 3.13",
|
|
12
12
|
]
|
|
13
13
|
dependencies = [
|
|
14
|
-
"dirigent-block-execute==0.
|
|
15
|
-
"dirigent-blocks==0.
|
|
16
|
-
"dirigent-client==0.
|
|
17
|
-
"dirigent-common==0.
|
|
18
|
-
"dirigent-core==0.
|
|
19
|
-
"dirigent-examples==0.
|
|
20
|
-
"dirigent-plugin==0.
|
|
21
|
-
"dirigent-server==0.
|
|
14
|
+
"dirigent-block-execute==0.21.0",
|
|
15
|
+
"dirigent-blocks==0.21.0",
|
|
16
|
+
"dirigent-client==0.21.0",
|
|
17
|
+
"dirigent-common==0.21.0",
|
|
18
|
+
"dirigent-core==0.21.0",
|
|
19
|
+
"dirigent-examples==0.21.0",
|
|
20
|
+
"dirigent-plugin==0.21.0",
|
|
21
|
+
"dirigent-server==0.21.0",
|
|
22
22
|
"httpx2>=2.12.0",
|
|
23
23
|
"python-dotenv>=1.1.0",
|
|
24
24
|
"pyyaml>=6.0.3",
|
|
@@ -350,7 +350,9 @@ def apply_command(
|
|
|
350
350
|
as_code: Annotated[str | None, typer.Option("--as", help="Register under a different code.")] = None,
|
|
351
351
|
paused: Annotated[
|
|
352
352
|
bool,
|
|
353
|
-
typer.Option(
|
|
353
|
+
typer.Option(
|
|
354
|
+
"--paused", help="Create the schedules and watches this apply mints paused; existing ones are untouched."
|
|
355
|
+
),
|
|
354
356
|
] = False,
|
|
355
357
|
prune: Annotated[
|
|
356
358
|
bool,
|
|
@@ -645,7 +645,8 @@ async def run_document(
|
|
|
645
645
|
async with session_scope(sessions) as session:
|
|
646
646
|
await _apply_supporting(session, services, extra_definition)
|
|
647
647
|
async with session_scope(sessions) as session:
|
|
648
|
-
|
|
648
|
+
# Triggers land paused: the instance runs only the run it was asked for.
|
|
649
|
+
applied = await apply_document(session, services, definition, pause_schedules=True)
|
|
649
650
|
if not applied.plan.ok:
|
|
650
651
|
raise LocalError(
|
|
651
652
|
"the document does not validate against the installed catalog:\n"
|
|
@@ -697,8 +698,8 @@ def _parse_supporting(text: str) -> PipelineDefinition:
|
|
|
697
698
|
|
|
698
699
|
|
|
699
700
|
async def _apply_supporting(session: AsyncSession, services: EngineServices, supporting: PipelineDefinition) -> None:
|
|
700
|
-
"""Apply one document a run depends on, without running it."""
|
|
701
|
-
applied = await apply_document(session, services, supporting)
|
|
701
|
+
"""Apply one document a run depends on, without running it or arming its triggers."""
|
|
702
|
+
applied = await apply_document(session, services, supporting, pause_schedules=True)
|
|
702
703
|
if not applied.plan.ok:
|
|
703
704
|
raise LocalError(
|
|
704
705
|
f"the supporting document {supporting.code!r} does not validate:\n"
|
|
@@ -127,6 +127,7 @@ app.add_typer(commands.schema_app, rich_help_panel=DEFINE_PANEL)
|
|
|
127
127
|
app.add_typer(commands.connection_app, rich_help_panel=CONNECT_PANEL)
|
|
128
128
|
app.add_typer(triggers.schedule_app, rich_help_panel=TRIGGER_PANEL)
|
|
129
129
|
app.add_typer(triggers.webhook_app, rich_help_panel=TRIGGER_PANEL)
|
|
130
|
+
app.add_typer(triggers.watch_app, rich_help_panel=TRIGGER_PANEL)
|
|
130
131
|
app.add_typer(triggers.trigger_document_app, rich_help_panel=TRIGGER_PANEL)
|
|
131
132
|
app.add_typer(triggers.alerts_app, rich_help_panel=TRIGGER_PANEL)
|
|
132
133
|
app.add_typer(docker_app, rich_help_panel=PROCESS_PANEL)
|
|
@@ -911,7 +912,7 @@ def dev(
|
|
|
911
912
|
typer.Option(
|
|
912
913
|
"--seed",
|
|
913
914
|
help="Apply every dirigent/v1 document under this directory once the API answers, "
|
|
914
|
-
"with its schedules paused; name it more than once to seed one directory after another.",
|
|
915
|
+
"with its schedules and watches paused; name it more than once to seed one directory after another.",
|
|
915
916
|
),
|
|
916
917
|
] = None,
|
|
917
918
|
seed_installed: Annotated[
|
|
@@ -934,7 +935,7 @@ def dev(
|
|
|
934
935
|
|
|
935
936
|
--seed fills the instance from a directory of documents the moment it answers: the
|
|
936
937
|
connections a file or a document declares are created first, then every document is
|
|
937
|
-
applied with its schedules paused. A document an instance will not store is reported
|
|
938
|
+
applied with its schedules and watches paused. A document an instance will not store is reported
|
|
938
939
|
and passed over, because a corpus holds those on purpose.
|
|
939
940
|
"""
|
|
940
941
|
import asyncio
|
|
@@ -136,7 +136,7 @@ async def _connection(client: Dirigent, spec: ConnectionSpec) -> str:
|
|
|
136
136
|
|
|
137
137
|
|
|
138
138
|
async def _apply(client: Dirigent, raw: JsonMap, origin: str) -> Record:
|
|
139
|
-
"""Apply one document with its schedules paused, without the sections it carries."""
|
|
139
|
+
"""Apply one document with its schedules and watches paused, without the sections it carries."""
|
|
140
140
|
document = {name: value for name, value in raw.items() if name not in CARRIED}
|
|
141
141
|
try:
|
|
142
142
|
result = await client.pipelines.apply(
|
|
@@ -157,6 +157,7 @@ async def _apply(client: Dirigent, raw: JsonMap, origin: str) -> Record:
|
|
|
157
157
|
pipeline=result.plan.code,
|
|
158
158
|
action=result.plan.action.value,
|
|
159
159
|
schedules_paused=result.triggers.schedules_created,
|
|
160
|
+
watches_paused=result.triggers.watches_created,
|
|
160
161
|
)
|
|
161
162
|
|
|
162
163
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""The trigger and alerting command groups: schedules, webhooks, and alert rules."""
|
|
1
|
+
"""The trigger and alerting command groups: schedules, webhooks, watches, and alert rules."""
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from typing import Annotated, Any, cast
|
|
@@ -35,6 +35,11 @@ schedule_app = typer.Typer(
|
|
|
35
35
|
name="schedule", help="A pipeline's clocks: cron, interval, or one-time.", no_args_is_help=True
|
|
36
36
|
)
|
|
37
37
|
webhook_app = typer.Typer(name="webhook", help="Inbound webhooks and their delivery history.", no_args_is_help=True)
|
|
38
|
+
watch_app = typer.Typer(
|
|
39
|
+
name="watch",
|
|
40
|
+
help="Sensors kept waiting: one run always waiting on each, the next armed on success.",
|
|
41
|
+
no_args_is_help=True,
|
|
42
|
+
)
|
|
38
43
|
trigger_document_app = typer.Typer(
|
|
39
44
|
name="trigger-document",
|
|
40
45
|
help="Documents that declare clocks for a pipeline defined elsewhere.",
|
|
@@ -246,6 +251,60 @@ def schedule_delete(
|
|
|
246
251
|
emit_fact("schedule.deleted", message="deleted", code=code, pipeline=pipeline)
|
|
247
252
|
|
|
248
253
|
|
|
254
|
+
@watch_app.command("list")
|
|
255
|
+
def watch_list(
|
|
256
|
+
ctx: typer.Context,
|
|
257
|
+
pipeline: Annotated[str, typer.Argument(help="The pipeline whose watches to list.")],
|
|
258
|
+
) -> None:
|
|
259
|
+
"""List a pipeline's watches, each with the run it has waiting and how its waits are going."""
|
|
260
|
+
with client_for(state_of(ctx)) as dg:
|
|
261
|
+
rows = list(paged(lambda after, size: dg.call(dg.watches.list(pipeline, after=after, limit=size)), None))
|
|
262
|
+
emit_records("watch", rows)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
@watch_app.command("show")
|
|
266
|
+
def watch_show(
|
|
267
|
+
ctx: typer.Context,
|
|
268
|
+
pipeline: Annotated[str, typer.Argument(help="The pipeline the watch belongs to.")],
|
|
269
|
+
code: Annotated[str, typer.Argument(help="The watch to show.")],
|
|
270
|
+
) -> None:
|
|
271
|
+
"""Show one watch: the step it waits on, where it left off, and its last error."""
|
|
272
|
+
with client_for(state_of(ctx)) as dg:
|
|
273
|
+
row = dg.call(dg.watches.get(pipeline, code))
|
|
274
|
+
emit_one("watch", row)
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
@watch_app.command("pause")
|
|
278
|
+
def watch_pause(
|
|
279
|
+
ctx: typer.Context,
|
|
280
|
+
pipeline: Annotated[str, typer.Argument()],
|
|
281
|
+
code: Annotated[str, typer.Argument()],
|
|
282
|
+
) -> None:
|
|
283
|
+
"""Stop a watch, cancelling the run it has waiting, and keep where it left off."""
|
|
284
|
+
with client_for(state_of(ctx)) as dg:
|
|
285
|
+
row = dg.call(dg.watches.pause(pipeline, code))
|
|
286
|
+
emit_fact("watch.paused", message="paused", code=code, pipeline=pipeline, cursor=row.cursor)
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
@watch_app.command("resume")
|
|
290
|
+
def watch_resume(
|
|
291
|
+
ctx: typer.Context,
|
|
292
|
+
pipeline: Annotated[str, typer.Argument()],
|
|
293
|
+
code: Annotated[str, typer.Argument()],
|
|
294
|
+
) -> None:
|
|
295
|
+
"""Start a watch again, arming a run from where its last success left off."""
|
|
296
|
+
with client_for(state_of(ctx)) as dg:
|
|
297
|
+
row = dg.call(dg.watches.resume(pipeline, code))
|
|
298
|
+
emit_fact(
|
|
299
|
+
"watch.resumed",
|
|
300
|
+
message="resumed",
|
|
301
|
+
code=code,
|
|
302
|
+
pipeline=pipeline,
|
|
303
|
+
waiting_run_id=row.waiting_run_id,
|
|
304
|
+
cursor=row.cursor,
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
|
|
249
308
|
def _print_token(minted: WebhookTokenOut, *, base_url: str) -> None:
|
|
250
309
|
"""Print a minted token once, with the URL already assembled.
|
|
251
310
|
|
|
@@ -621,7 +680,7 @@ def trigger_document_show(
|
|
|
621
680
|
ctx: typer.Context,
|
|
622
681
|
code: Annotated[str, typer.Argument(help="The triggers document to read.")],
|
|
623
682
|
) -> None:
|
|
624
|
-
"""Show one triggers document and the schedules and
|
|
683
|
+
"""Show one triggers document and the schedules, webhooks and watches it owns."""
|
|
625
684
|
with client_for(state_of(ctx)) as dg:
|
|
626
685
|
detail = dg.call(dg.trigger_documents.get(code))
|
|
627
686
|
if state_of(ctx).json_output:
|
|
@@ -631,6 +690,7 @@ def trigger_document_show(
|
|
|
631
690
|
console.print(f" digest [dim]{detail.digest}[/]")
|
|
632
691
|
console.print(f" schedules {', '.join(detail.schedules) or '-'}")
|
|
633
692
|
console.print(f" webhooks {', '.join(detail.webhooks) or '-'}")
|
|
693
|
+
console.print(f" watches {', '.join(detail.watches) or '-'}")
|
|
634
694
|
if detail.description:
|
|
635
695
|
console.print(f"\n{detail.description}")
|
|
636
696
|
|
|
@@ -643,7 +703,14 @@ def trigger_document_delete(
|
|
|
643
703
|
"""Remove a triggers document and every schedule and webhook it declared."""
|
|
644
704
|
with client_for(state_of(ctx)) as dg:
|
|
645
705
|
dg.call(dg.trigger_documents.delete(code))
|
|
646
|
-
emit_fact(
|
|
706
|
+
emit_fact(
|
|
707
|
+
"trigger_document.deleted",
|
|
708
|
+
message="deleted",
|
|
709
|
+
code=code,
|
|
710
|
+
schedules="deleted",
|
|
711
|
+
webhooks="deleted",
|
|
712
|
+
watches="deleted",
|
|
713
|
+
)
|
|
647
714
|
|
|
648
715
|
|
|
649
716
|
@alerts_app.command("retry")
|
|
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
|
{dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/templates/pack/__init__.py.tmpl
RENAMED
|
File without changes
|
{dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/templates/pack/operator.py.tmpl
RENAMED
|
File without changes
|
{dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/templates/pack/pyproject.toml.tmpl
RENAMED
|
File without changes
|
{dirigent_cli-0.20.0 → dirigent_cli-0.21.0}/src/dirigent_cli/templates/pack/test_plugin.py.tmpl
RENAMED
|
File without changes
|
|
File without changes
|