dirigent-client 0.26.0__tar.gz → 0.27.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_client-0.26.0 → dirigent_client-0.27.0}/PKG-INFO +2 -2
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/pyproject.toml +2 -2
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/pyproject.toml.orig +2 -2
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/__init__.py +0 -14
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/client.py +0 -6
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/enums.py +14 -19
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/sources.py +14 -2
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/trigger_documents.py +2 -2
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/schemas/__init__.py +2 -12
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/schemas/pipelines.py +3 -25
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/schemas/runs.py +1 -1
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/schemas/sources.py +38 -7
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/schemas/triggers.py +2 -114
- dirigent_client-0.26.0/src/dirigent_client/resources/watches.py +0 -29
- dirigent_client-0.26.0/src/dirigent_client/resources/webhooks.py +0 -80
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/LICENSE +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/README.md +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/errors.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/messages.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/py.typed +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/__init__.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/alerts.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/auth.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/base.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/blocks.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/connections.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/examples.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/pipelines.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/runs.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/schedules.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/schemas.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/system.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/schemas/alerts.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/schemas/auth.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/schemas/catalog.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/schemas/common.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/schemas/connections.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/schemas/examples.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/schemas/labels.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/schemas/schemas.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/schemas/system.py +0 -0
- {dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/transport.py +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dirigent-client
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.27.0
|
|
4
4
|
Summary: The dirigent API contract: typed wire schemas and an async Python client.
|
|
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-common==0.
|
|
9
|
+
Requires-Dist: dirigent-common==0.27.0
|
|
10
10
|
Requires-Dist: httpx2>=2.12.0
|
|
11
11
|
Requires-Dist: pydantic>=2.13.5
|
|
12
12
|
Requires-Dist: pyyaml>=6.0.3
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "dirigent-client"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.27.0"
|
|
4
4
|
description = "The dirigent API contract: typed wire schemas and an async Python client."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.13"
|
|
@@ -11,7 +11,7 @@ classifiers = [
|
|
|
11
11
|
"Programming Language :: Python :: 3.13",
|
|
12
12
|
]
|
|
13
13
|
dependencies = [
|
|
14
|
-
"dirigent-common==0.
|
|
14
|
+
"dirigent-common==0.27.0",
|
|
15
15
|
"httpx2>=2.12.0",
|
|
16
16
|
"pydantic>=2.13.5",
|
|
17
17
|
"pyyaml>=6.0.3",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "dirigent-client"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.27.0"
|
|
4
4
|
description = "The dirigent API contract: typed wire schemas and an async Python client."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.13"
|
|
@@ -11,7 +11,7 @@ classifiers = [
|
|
|
11
11
|
"Programming Language :: Python :: 3.13",
|
|
12
12
|
]
|
|
13
13
|
dependencies = [
|
|
14
|
-
"dirigent-common==0.
|
|
14
|
+
"dirigent-common==0.27.0",
|
|
15
15
|
"httpx2>=2.12.0",
|
|
16
16
|
"pydantic>=2.13.5",
|
|
17
17
|
"pyyaml>=6.0.3",
|
|
@@ -23,7 +23,6 @@ from dirigent_client.enums import (
|
|
|
23
23
|
TokenKind,
|
|
24
24
|
TriggerKind,
|
|
25
25
|
UserRole,
|
|
26
|
-
WebhookOutcome,
|
|
27
26
|
WorkerStatus,
|
|
28
27
|
)
|
|
29
28
|
from dirigent_client.errors import (
|
|
@@ -68,14 +67,12 @@ from dirigent_client.schemas import (
|
|
|
68
67
|
ConnectionUpdate,
|
|
69
68
|
DagNode,
|
|
70
69
|
DagView,
|
|
71
|
-
DeliveryOut,
|
|
72
70
|
DiffSummary,
|
|
73
71
|
EndpointInput,
|
|
74
72
|
ExampleDetail,
|
|
75
73
|
ExampleOut,
|
|
76
74
|
FiringOut,
|
|
77
75
|
Health,
|
|
78
|
-
HookAccepted,
|
|
79
76
|
Identity,
|
|
80
77
|
InputAccepted,
|
|
81
78
|
IssuedTokenOut,
|
|
@@ -125,10 +122,6 @@ from dirigent_client.schemas import (
|
|
|
125
122
|
UserIn,
|
|
126
123
|
UserOut,
|
|
127
124
|
ValidationIssue,
|
|
128
|
-
WatchOut,
|
|
129
|
-
WebhookIn,
|
|
130
|
-
WebhookOut,
|
|
131
|
-
WebhookTokenOut,
|
|
132
125
|
WorkerOut,
|
|
133
126
|
)
|
|
134
127
|
from dirigent_client.transport import (
|
|
@@ -193,7 +186,6 @@ __all__ = [
|
|
|
193
186
|
"DagNode",
|
|
194
187
|
"DagView",
|
|
195
188
|
"DocumentKind",
|
|
196
|
-
"DeliveryOut",
|
|
197
189
|
"DiffSummary",
|
|
198
190
|
"ExampleDetail",
|
|
199
191
|
"ExampleOut",
|
|
@@ -203,7 +195,6 @@ __all__ = [
|
|
|
203
195
|
"FiringOutcome",
|
|
204
196
|
"Forbidden",
|
|
205
197
|
"Health",
|
|
206
|
-
"HookAccepted",
|
|
207
198
|
"Identity",
|
|
208
199
|
"Importance",
|
|
209
200
|
"IssuedTokenOut",
|
|
@@ -264,11 +255,6 @@ __all__ = [
|
|
|
264
255
|
"ValidationFailed",
|
|
265
256
|
"ValidationIssue",
|
|
266
257
|
"WaitTimeout",
|
|
267
|
-
"WebhookIn",
|
|
268
|
-
"WebhookOut",
|
|
269
|
-
"WebhookOutcome",
|
|
270
|
-
"WatchOut",
|
|
271
|
-
"WebhookTokenOut",
|
|
272
258
|
"WorkerOut",
|
|
273
259
|
"WorkerStatus",
|
|
274
260
|
"declared_label",
|
|
@@ -19,8 +19,6 @@ from dirigent_client.resources.schemas import Schemas
|
|
|
19
19
|
from dirigent_client.resources.sources import Sources
|
|
20
20
|
from dirigent_client.resources.system import System, Workers
|
|
21
21
|
from dirigent_client.resources.trigger_documents import TriggerDocuments
|
|
22
|
-
from dirigent_client.resources.watches import Watches
|
|
23
|
-
from dirigent_client.resources.webhooks import Webhooks
|
|
24
22
|
from dirigent_client.transport import (
|
|
25
23
|
API_PREFIX,
|
|
26
24
|
DEFAULT_CONNECT_TIMEOUT,
|
|
@@ -65,8 +63,6 @@ class Dirigent:
|
|
|
65
63
|
self.blocks = Blocks(self.transport)
|
|
66
64
|
self.examples = Examples(self.transport)
|
|
67
65
|
self.schedules = Schedules(self.transport)
|
|
68
|
-
self.webhooks = Webhooks(self.transport)
|
|
69
|
-
self.watches = Watches(self.transport)
|
|
70
66
|
self.sources = Sources(self.transport)
|
|
71
67
|
self.trigger_documents = TriggerDocuments(self.transport)
|
|
72
68
|
self.alerts = Alerts(self.transport)
|
|
@@ -110,8 +106,6 @@ class BlockingDirigent:
|
|
|
110
106
|
self.blocks = self.client.blocks
|
|
111
107
|
self.examples = self.client.examples
|
|
112
108
|
self.schedules = self.client.schedules
|
|
113
|
-
self.webhooks = self.client.webhooks
|
|
114
|
-
self.watches = self.client.watches
|
|
115
109
|
self.sources = self.client.sources
|
|
116
110
|
self.trigger_documents = self.client.trigger_documents
|
|
117
111
|
self.alerts = self.client.alerts
|
|
@@ -103,7 +103,6 @@ class TriggerKind(StrEnum):
|
|
|
103
103
|
|
|
104
104
|
ADHOC = "adhoc"
|
|
105
105
|
SCHEDULE = "schedule"
|
|
106
|
-
WEBHOOK = "webhook"
|
|
107
106
|
API_TOKEN = "api_token"
|
|
108
107
|
USER = "user"
|
|
109
108
|
PIPELINE = "pipeline"
|
|
@@ -112,9 +111,6 @@ class TriggerKind(StrEnum):
|
|
|
112
111
|
BACKFILL = "backfill"
|
|
113
112
|
"""A backfill over past windows created this one, and ``triggered_by_id`` names the schedule."""
|
|
114
113
|
|
|
115
|
-
WATCH = "watch"
|
|
116
|
-
"""A watch armed this one to wait on its sensor, and ``triggered_by_id`` names the watch."""
|
|
117
|
-
|
|
118
114
|
SOURCE = "source"
|
|
119
115
|
"""An input arrived at a source node, and ``triggered_by_id`` names the source."""
|
|
120
116
|
|
|
@@ -178,25 +174,18 @@ class FiringOutcome(StrEnum):
|
|
|
178
174
|
"""The run could not be created at all, and the reason is on the row."""
|
|
179
175
|
|
|
180
176
|
|
|
181
|
-
class WebhookOutcome(StrEnum):
|
|
182
|
-
"""What the intake endpoint did with one delivery."""
|
|
183
|
-
|
|
184
|
-
ACCEPTED = "accepted"
|
|
185
|
-
"""The payload mapped, validated, and started a run."""
|
|
186
|
-
|
|
187
|
-
SKIPPED = "skipped"
|
|
188
|
-
"""The payload was good, but the pipeline's concurrency policy dropped the run."""
|
|
189
|
-
|
|
190
|
-
REJECTED = "rejected"
|
|
191
|
-
"""The delivery was refused, and the reason is on the row."""
|
|
192
|
-
|
|
193
|
-
|
|
194
177
|
class SourceState(StrEnum):
|
|
195
178
|
"""Whether a source takes inputs now, read from its row and the runs it has unsettled."""
|
|
196
179
|
|
|
180
|
+
STARTING = "starting"
|
|
181
|
+
"""A worker has yet to poll it successfully for the first time."""
|
|
182
|
+
|
|
197
183
|
LISTENING = "listening"
|
|
198
184
|
"""It takes inputs."""
|
|
199
185
|
|
|
186
|
+
FAILING = "failing"
|
|
187
|
+
"""Its last polls failed, and the next one waits out a backoff."""
|
|
188
|
+
|
|
200
189
|
BACKLOGGED = "backlogged"
|
|
201
190
|
"""As many runs from it are unsettled as ``max_in_flight`` allows; a new input is refused 503."""
|
|
202
191
|
|
|
@@ -211,11 +200,17 @@ class InputOutcome(StrEnum):
|
|
|
211
200
|
"""What came of one input that reached a source."""
|
|
212
201
|
|
|
213
202
|
ACCEPTED = "accepted"
|
|
214
|
-
"""It became a run, and the caller was answered with where to read it."""
|
|
203
|
+
"""It became a run, and the caller was answered with where to read it, or is held for its reply."""
|
|
204
|
+
|
|
205
|
+
REPLIED = "replied"
|
|
206
|
+
"""It became a run whose answer the caller was held for: a reply, or the run's failure."""
|
|
215
207
|
|
|
216
208
|
REFUSED = "refused"
|
|
217
209
|
"""It was refused before any run existed, and the reason is on the row."""
|
|
218
210
|
|
|
211
|
+
TIMED_OUT = "timed_out"
|
|
212
|
+
"""It became a run the caller was held for, and no answer came before the caller's timeout."""
|
|
213
|
+
|
|
219
214
|
|
|
220
215
|
class BodyKind(StrEnum):
|
|
221
216
|
"""How an inbound request's body was read."""
|
|
@@ -240,7 +235,7 @@ class DocumentKind(StrEnum):
|
|
|
240
235
|
|
|
241
236
|
PIPELINE = "pipeline"
|
|
242
237
|
TRIGGERS = "triggers"
|
|
243
|
-
"""Clocks
|
|
238
|
+
"""Clocks for a pipeline defined somewhere else."""
|
|
244
239
|
|
|
245
240
|
|
|
246
241
|
class ProvenanceSource(StrEnum):
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"""A pipeline's sources: what each listens to, its state, what has arrived, and its token."""
|
|
2
2
|
|
|
3
|
+
from pydantic import SecretStr
|
|
4
|
+
|
|
3
5
|
from dirigent_client.resources.base import Resource, query
|
|
4
|
-
from dirigent_client.schemas import Page, SourceInputOut, SourceOut, SourceTokenOut
|
|
6
|
+
from dirigent_client.schemas import Page, SetSecretRequest, SourceInputOut, SourceOut, SourceTokenOut
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
class Sources(Resource):
|
|
@@ -27,9 +29,19 @@ class Sources(Resource):
|
|
|
27
29
|
return await self._one(SourceOut, "POST", f"/pipelines/{pipeline}/sources/{code}/$resume")
|
|
28
30
|
|
|
29
31
|
async def rotate_token(self, pipeline: str, code: str) -> SourceTokenOut:
|
|
30
|
-
"""Mint a new token and forget the old one immediately; every caller has to be given it."""
|
|
32
|
+
"""Mint a new token or signing secret and forget the old one immediately; every caller has to be given it."""
|
|
31
33
|
return await self._one(SourceTokenOut, "POST", f"/pipelines/{pipeline}/sources/{code}/$rotate-token")
|
|
32
34
|
|
|
35
|
+
async def set_secret(self, pipeline: str, code: str, secret: str) -> SourceOut:
|
|
36
|
+
"""Replace a signed source's signing secret with one its sender issued."""
|
|
37
|
+
body = SetSecretRequest(secret=SecretStr(secret))
|
|
38
|
+
return await self._one(
|
|
39
|
+
SourceOut,
|
|
40
|
+
"POST",
|
|
41
|
+
f"/pipelines/{pipeline}/sources/{code}/$set-secret",
|
|
42
|
+
json={"secret": body.secret.get_secret_value()},
|
|
43
|
+
)
|
|
44
|
+
|
|
33
45
|
async def inputs(
|
|
34
46
|
self, pipeline: str, code: str, *, after: str | None = None, limit: int | None = None
|
|
35
47
|
) -> Page[SourceInputOut]:
|
{dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/trigger_documents.py
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Triggers documents: the clocks
|
|
1
|
+
"""Triggers documents: the clocks one document declares for another's pipeline."""
|
|
2
2
|
|
|
3
3
|
from dirigent_client.resources.base import Resource, query
|
|
4
4
|
from dirigent_client.schemas import Page, TriggerDocumentDetail, TriggerDocumentOut
|
|
@@ -16,5 +16,5 @@ class TriggerDocuments(Resource):
|
|
|
16
16
|
return await self._one(TriggerDocumentDetail, "GET", f"/trigger-documents/{code}")
|
|
17
17
|
|
|
18
18
|
async def delete(self, code: str) -> None:
|
|
19
|
-
"""Remove a triggers document and every schedule
|
|
19
|
+
"""Remove a triggers document and every schedule it owns."""
|
|
20
20
|
await self._transport.request("DELETE", f"/trigger-documents/{code}")
|
|
@@ -68,6 +68,7 @@ from dirigent_client.schemas.sources import (
|
|
|
68
68
|
EndpointInput,
|
|
69
69
|
InputAccepted,
|
|
70
70
|
RequestFacts,
|
|
71
|
+
SetSecretRequest,
|
|
71
72
|
SourceChanges,
|
|
72
73
|
SourceInputOut,
|
|
73
74
|
SourceOut,
|
|
@@ -83,19 +84,13 @@ from dirigent_client.schemas.system import (
|
|
|
83
84
|
WorkerOut,
|
|
84
85
|
)
|
|
85
86
|
from dirigent_client.schemas.triggers import (
|
|
86
|
-
DeliveryOut,
|
|
87
87
|
FiringOut,
|
|
88
|
-
HookAccepted,
|
|
89
88
|
ScheduleIn,
|
|
90
89
|
ScheduleOut,
|
|
91
90
|
SchedulePreview,
|
|
92
91
|
SchedulePreviewRequest,
|
|
93
92
|
TriggerDocumentDetail,
|
|
94
93
|
TriggerDocumentOut,
|
|
95
|
-
WatchOut,
|
|
96
|
-
WebhookIn,
|
|
97
|
-
WebhookOut,
|
|
98
|
-
WebhookTokenOut,
|
|
99
94
|
)
|
|
100
95
|
from dirigent_common import JsonList, JsonMap
|
|
101
96
|
|
|
@@ -122,7 +117,6 @@ __all__ = [
|
|
|
122
117
|
"ConnectionUpdate",
|
|
123
118
|
"DagNode",
|
|
124
119
|
"DagView",
|
|
125
|
-
"DeliveryOut",
|
|
126
120
|
"DiffSummary",
|
|
127
121
|
"EndpointInput",
|
|
128
122
|
"InputAccepted",
|
|
@@ -130,7 +124,6 @@ __all__ = [
|
|
|
130
124
|
"ExampleOut",
|
|
131
125
|
"FiringOut",
|
|
132
126
|
"Health",
|
|
133
|
-
"HookAccepted",
|
|
134
127
|
"Identity",
|
|
135
128
|
"IssuedTokenOut",
|
|
136
129
|
"ItemOut",
|
|
@@ -159,6 +152,7 @@ __all__ = [
|
|
|
159
152
|
"SourceChanges",
|
|
160
153
|
"SourceInputOut",
|
|
161
154
|
"SourceOut",
|
|
155
|
+
"SetSecretRequest",
|
|
162
156
|
"SourceTokenOut",
|
|
163
157
|
"Requirements",
|
|
164
158
|
"RunAccepted",
|
|
@@ -190,9 +184,5 @@ __all__ = [
|
|
|
190
184
|
"UserOut",
|
|
191
185
|
"UserUpdate",
|
|
192
186
|
"ValidationIssue",
|
|
193
|
-
"WatchOut",
|
|
194
|
-
"WebhookIn",
|
|
195
|
-
"WebhookOut",
|
|
196
|
-
"WebhookTokenOut",
|
|
197
187
|
"WorkerOut",
|
|
198
188
|
]
|
|
@@ -76,12 +76,6 @@ class PipelineOut(WireModel):
|
|
|
76
76
|
schedules: int = 0
|
|
77
77
|
"""How many clocks fire this pipeline."""
|
|
78
78
|
|
|
79
|
-
webhooks: int = 0
|
|
80
|
-
"""How many inbound endpoints fire this pipeline."""
|
|
81
|
-
|
|
82
|
-
watches: int = 0
|
|
83
|
-
"""How many watches keep a run of this pipeline waiting on a sensor."""
|
|
84
|
-
|
|
85
79
|
last_run: LastRun | None = None
|
|
86
80
|
"""How the newest run of this pipeline went, or nothing when it has never run."""
|
|
87
81
|
|
|
@@ -116,7 +110,7 @@ class ApplyRequest(BaseModel):
|
|
|
116
110
|
source_ref: str | None = Field(default=None, description="The file path or URL the document came from.")
|
|
117
111
|
pause_schedules: bool = Field(
|
|
118
112
|
default=False,
|
|
119
|
-
description="Create the schedules
|
|
113
|
+
description="Create the schedules this apply brings into being already paused.",
|
|
120
114
|
)
|
|
121
115
|
|
|
122
116
|
|
|
@@ -336,27 +330,11 @@ class Materialized(WireModel):
|
|
|
336
330
|
schedules_created: list[str] = Field(default_factory=list[str])
|
|
337
331
|
schedules_updated: list[str] = Field(default_factory=list[str])
|
|
338
332
|
schedules_removed: list[str] = Field(default_factory=list[str])
|
|
339
|
-
webhooks_created: list[str] = Field(default_factory=list[str])
|
|
340
|
-
webhooks_updated: list[str] = Field(default_factory=list[str])
|
|
341
|
-
webhooks_removed: list[str] = Field(default_factory=list[str])
|
|
342
|
-
watches_created: list[str] = Field(default_factory=list[str])
|
|
343
|
-
watches_updated: list[str] = Field(default_factory=list[str])
|
|
344
|
-
watches_removed: list[str] = Field(default_factory=list[str])
|
|
345
333
|
|
|
346
334
|
@property
|
|
347
335
|
def empty(self) -> bool:
|
|
348
336
|
"""Report whether the apply left every trigger exactly as it was."""
|
|
349
|
-
return not (
|
|
350
|
-
self.schedules_created
|
|
351
|
-
or self.schedules_updated
|
|
352
|
-
or self.schedules_removed
|
|
353
|
-
or self.webhooks_created
|
|
354
|
-
or self.webhooks_updated
|
|
355
|
-
or self.webhooks_removed
|
|
356
|
-
or self.watches_created
|
|
357
|
-
or self.watches_updated
|
|
358
|
-
or self.watches_removed
|
|
359
|
-
)
|
|
337
|
+
return not (self.schedules_created or self.schedules_updated or self.schedules_removed)
|
|
360
338
|
|
|
361
339
|
|
|
362
340
|
class PipelinePlan(WireModel):
|
|
@@ -395,7 +373,7 @@ class ApplyResult(WireModel):
|
|
|
395
373
|
version: int | None = None
|
|
396
374
|
dry_run: bool = False
|
|
397
375
|
triggers: Materialized = Field(default_factory=Materialized)
|
|
398
|
-
"""Which schedules
|
|
376
|
+
"""Which schedules the document's ``triggers:`` section created, changed, or retired."""
|
|
399
377
|
|
|
400
378
|
sources: SourceChanges = Field(default_factory=SourceChanges)
|
|
401
379
|
"""Which source rows the apply created, changed, or retired, and the tokens it minted."""
|
|
@@ -44,7 +44,7 @@ class RunOut(WireModel):
|
|
|
44
44
|
parent_run_id: UUID | None = None
|
|
45
45
|
"""The run whose step started this one, when a step of another run did."""
|
|
46
46
|
triggered_by_id: UUID | None = None
|
|
47
|
-
"""What started the run: the source, schedule,
|
|
47
|
+
"""What started the run: the source, schedule, token or user, as its id."""
|
|
48
48
|
|
|
49
49
|
triggered_by_label: str | None = None
|
|
50
50
|
source: str | None = None
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
from uuid import UUID
|
|
5
5
|
|
|
6
|
-
from pydantic import BaseModel, ConfigDict, Field, JsonValue
|
|
6
|
+
from pydantic import BaseModel, ConfigDict, Field, JsonValue, SecretStr
|
|
7
7
|
|
|
8
8
|
from dirigent_client.enums import BodyKind, InputOutcome, SourceState
|
|
9
9
|
from dirigent_client.schemas.common import WireModel
|
|
@@ -86,7 +86,10 @@ class SourceOut(WireModel):
|
|
|
86
86
|
"""How a caller of a received source authenticates: ``token`` or ``public``."""
|
|
87
87
|
|
|
88
88
|
token_prefix: str | None = None
|
|
89
|
-
"""The leading characters of the token, so a caller's copy can be told apart
|
|
89
|
+
"""The leading characters of the token or the signing secret, so a caller's copy can be told apart."""
|
|
90
|
+
|
|
91
|
+
signature_header: str | None = None
|
|
92
|
+
"""For an ``hmac`` source, the header a caller's signature of the body arrives in."""
|
|
90
93
|
|
|
91
94
|
in_flight: int = 0
|
|
92
95
|
"""How many runs it started are unsettled."""
|
|
@@ -101,21 +104,46 @@ class SourceOut(WireModel):
|
|
|
101
104
|
"""How many inputs were refused once their caller was let in."""
|
|
102
105
|
|
|
103
106
|
last_input_at: datetime | None = None
|
|
107
|
+
summary: str | None = None
|
|
108
|
+
"""What the source listens to, in one line its kind writes, such as the prefix it polls."""
|
|
109
|
+
|
|
110
|
+
polled_at: datetime | None = None
|
|
111
|
+
"""When a poll of a polled source last succeeded."""
|
|
112
|
+
|
|
113
|
+
next_poll_at: datetime | None = None
|
|
114
|
+
failures: int = 0
|
|
115
|
+
"""How many polls in a row have failed."""
|
|
116
|
+
|
|
117
|
+
last_error: str | None = None
|
|
104
118
|
created_at: datetime
|
|
105
119
|
|
|
106
120
|
|
|
107
121
|
class SourceTokenOut(WireModel):
|
|
108
|
-
"""A
|
|
122
|
+
"""A credential freshly minted for a source, returned once and never readable again."""
|
|
109
123
|
|
|
110
124
|
source_id: UUID
|
|
111
125
|
pipeline: str
|
|
112
126
|
code: str
|
|
127
|
+
auth: str = "token"
|
|
128
|
+
"""``token`` for a bearer token a caller presents, ``hmac`` for a secret a caller signs the body with."""
|
|
129
|
+
|
|
130
|
+
header: str | None = None
|
|
131
|
+
"""For ``hmac``, the header the signature arrives in."""
|
|
132
|
+
|
|
113
133
|
token: str
|
|
134
|
+
"""The token, or the signing secret."""
|
|
135
|
+
|
|
114
136
|
prefix: str
|
|
115
137
|
url_path: str
|
|
116
138
|
"""Where the source is called, so a caller can be configured without assembling the path by hand."""
|
|
117
139
|
|
|
118
140
|
|
|
141
|
+
class SetSecretRequest(WireModel):
|
|
142
|
+
"""The signing secret a sender issued, to replace the one the instance minted."""
|
|
143
|
+
|
|
144
|
+
secret: SecretStr
|
|
145
|
+
|
|
146
|
+
|
|
119
147
|
class SourceChanges(WireModel):
|
|
120
148
|
"""What applying a document did to the source rows its pipeline holds."""
|
|
121
149
|
|
|
@@ -137,8 +165,8 @@ class SourceInputOut(WireModel):
|
|
|
137
165
|
id: int
|
|
138
166
|
created_at: datetime
|
|
139
167
|
outcome: InputOutcome
|
|
140
|
-
status: int
|
|
141
|
-
"""The HTTP status the caller was answered with."""
|
|
168
|
+
status: int | None = None
|
|
169
|
+
"""The HTTP status the caller was answered with, or null for an input a worker polled."""
|
|
142
170
|
|
|
143
171
|
run_id: UUID | None = None
|
|
144
172
|
code: str | None = None
|
|
@@ -146,8 +174,11 @@ class SourceInputOut(WireModel):
|
|
|
146
174
|
|
|
147
175
|
reason: str | None = None
|
|
148
176
|
params: JsonMap | None = None
|
|
149
|
-
method: str
|
|
150
|
-
path: str
|
|
177
|
+
method: str | None = None
|
|
178
|
+
path: str | None = None
|
|
179
|
+
label: str | None = None
|
|
180
|
+
"""What a polled kind names the input, such as the object it found."""
|
|
181
|
+
|
|
151
182
|
body_bytes: int = 0
|
|
152
183
|
duration_ms: int = 0
|
|
153
184
|
caller: str | None = None
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"""A pipeline's persisted triggers: its schedules
|
|
1
|
+
"""A pipeline's persisted triggers: its schedules."""
|
|
2
2
|
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
from uuid import UUID
|
|
5
5
|
|
|
6
|
-
from pydantic import BaseModel, Field,
|
|
6
|
+
from pydantic import BaseModel, Field, field_validator
|
|
7
7
|
|
|
8
8
|
from dirigent_client.enums import (
|
|
9
9
|
FiringOutcome,
|
|
@@ -11,7 +11,6 @@ from dirigent_client.enums import (
|
|
|
11
11
|
ProvenanceSource,
|
|
12
12
|
RunPriority,
|
|
13
13
|
ScheduleKind,
|
|
14
|
-
WebhookOutcome,
|
|
15
14
|
)
|
|
16
15
|
from dirigent_client.messages import (
|
|
17
16
|
EMPTY_LOG_LEVEL_PATTERN,
|
|
@@ -112,84 +111,6 @@ class FiringOut(WireModel):
|
|
|
112
111
|
detail: str | None = None
|
|
113
112
|
|
|
114
113
|
|
|
115
|
-
class WebhookIn(BaseModel):
|
|
116
|
-
"""A webhook as a caller declares it; the token is never supplied, only minted."""
|
|
117
|
-
|
|
118
|
-
code: EntityName
|
|
119
|
-
name: str | None = None
|
|
120
|
-
description: str | None = None
|
|
121
|
-
params_from_payload: dict[str, str] = Field(default_factory=dict[str, str])
|
|
122
|
-
hmac_secret: SecretStr | None = Field(default=None, min_length=1)
|
|
123
|
-
"""The signing secret, or null for an unsigned webhook; an empty string is neither."""
|
|
124
|
-
|
|
125
|
-
rate_limit_per_minute: int = Field(default=60, ge=1)
|
|
126
|
-
priority: RunPriority | None = Field(
|
|
127
|
-
default=None,
|
|
128
|
-
description="The priority every accepted delivery's run carries. Omitted takes the pipeline's own.",
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
class WebhookOut(WireModel):
|
|
133
|
-
"""A webhook as a listing shows it: everything about it except the token."""
|
|
134
|
-
|
|
135
|
-
id: UUID
|
|
136
|
-
code: str
|
|
137
|
-
name: str | None = None
|
|
138
|
-
description: str | None = None
|
|
139
|
-
token_prefix: str
|
|
140
|
-
params_from_payload: dict[str, str] = Field(default_factory=dict[str, str])
|
|
141
|
-
signed: bool
|
|
142
|
-
"""Whether this webhook requires an HMAC signature; the secret itself never leaves."""
|
|
143
|
-
|
|
144
|
-
active: bool
|
|
145
|
-
managed: bool
|
|
146
|
-
trigger_document: str | None = None
|
|
147
|
-
"""The triggers document that declares this row, or null when the pipeline's own does."""
|
|
148
|
-
|
|
149
|
-
rate_limit_per_minute: int
|
|
150
|
-
priority: RunPriority | None = None
|
|
151
|
-
"""The priority every accepted delivery's run carries, or null when it takes the pipeline's own."""
|
|
152
|
-
|
|
153
|
-
last_delivery_at: datetime | None = None
|
|
154
|
-
created_at: datetime
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
class WatchOut(WireModel):
|
|
158
|
-
"""A watch as a listing shows it: what it waits on, and how its last run of waiting went."""
|
|
159
|
-
|
|
160
|
-
id: UUID
|
|
161
|
-
code: str
|
|
162
|
-
name: str | None = None
|
|
163
|
-
description: str | None = None
|
|
164
|
-
step: str
|
|
165
|
-
"""The root sensor step every run it arms waits on."""
|
|
166
|
-
|
|
167
|
-
params: JsonMap = Field(default_factory=dict)
|
|
168
|
-
paused: bool
|
|
169
|
-
managed: bool
|
|
170
|
-
trigger_document: str | None = None
|
|
171
|
-
"""The triggers document that declares this row, or null when the pipeline's own does."""
|
|
172
|
-
|
|
173
|
-
cursor: JsonMap | None = None
|
|
174
|
-
"""Where the last successful poke of the watched step left off, which the next run starts from."""
|
|
175
|
-
|
|
176
|
-
waiting_run_id: UUID | None = None
|
|
177
|
-
"""The run waiting on the sensor now, or null between one run and the next."""
|
|
178
|
-
|
|
179
|
-
failures: int = 0
|
|
180
|
-
"""How many waits in a row have ended without the sensor succeeding."""
|
|
181
|
-
|
|
182
|
-
last_error: str | None = None
|
|
183
|
-
"""Why the last wait ended without the sensor succeeding, or null once one has succeeded since."""
|
|
184
|
-
|
|
185
|
-
last_error_at: datetime | None = None
|
|
186
|
-
rearm_at: datetime | None = None
|
|
187
|
-
"""When a watch backing off after a failure arms its next run."""
|
|
188
|
-
|
|
189
|
-
last_armed_at: datetime | None = None
|
|
190
|
-
created_at: datetime
|
|
191
|
-
|
|
192
|
-
|
|
193
114
|
class TriggerDocumentOut(WireModel):
|
|
194
115
|
"""A ``kind: triggers`` document as a listing shows it."""
|
|
195
116
|
|
|
@@ -213,36 +134,3 @@ class TriggerDocumentDetail(TriggerDocumentOut):
|
|
|
213
134
|
|
|
214
135
|
document: JsonMap
|
|
215
136
|
schedules: list[str] = Field(default_factory=list[str])
|
|
216
|
-
webhooks: list[str] = Field(default_factory=list[str])
|
|
217
|
-
watches: list[str] = Field(default_factory=list[str])
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
class WebhookTokenOut(WireModel):
|
|
221
|
-
"""A freshly minted webhook token, returned once and never readable again."""
|
|
222
|
-
|
|
223
|
-
webhook_id: UUID
|
|
224
|
-
code: str
|
|
225
|
-
token: str
|
|
226
|
-
prefix: str
|
|
227
|
-
url_path: str
|
|
228
|
-
"""Where to POST, so a caller can be configured without assembling the path by hand."""
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
class HookAccepted(WireModel):
|
|
232
|
-
"""What an accepted delivery answers with: the run it started, or why it started none."""
|
|
233
|
-
|
|
234
|
-
run_id: UUID | None = None
|
|
235
|
-
outcome: WebhookOutcome
|
|
236
|
-
detail: str | None = None
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
class DeliveryOut(WireModel):
|
|
240
|
-
"""One inbound delivery, and what came of it."""
|
|
241
|
-
|
|
242
|
-
id: int
|
|
243
|
-
created_at: datetime
|
|
244
|
-
outcome: WebhookOutcome
|
|
245
|
-
run_id: UUID | None = None
|
|
246
|
-
reason: str | None = None
|
|
247
|
-
mapped_params: JsonMap | None = None
|
|
248
|
-
source: str | None = None
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"""A pipeline's watches: the sensor each keeps a run waiting on, and how that is going."""
|
|
2
|
-
|
|
3
|
-
from dirigent_client.resources.base import Resource, query
|
|
4
|
-
from dirigent_client.schemas import Page, WatchOut
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class Watches(Resource):
|
|
8
|
-
"""Read, pause, and resume the watches hanging from a pipeline."""
|
|
9
|
-
|
|
10
|
-
async def list(self, pipeline: str, *, after: str | None = None, limit: int | None = None) -> Page[WatchOut]:
|
|
11
|
-
"""List every watch on a pipeline, with the run each one has waiting."""
|
|
12
|
-
return await self._many(
|
|
13
|
-
WatchOut,
|
|
14
|
-
"GET",
|
|
15
|
-
f"/pipelines/{pipeline}/triggers/watches",
|
|
16
|
-
params=query(after=after, limit=limit),
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
async def get(self, pipeline: str, code: str) -> WatchOut:
|
|
20
|
-
"""Read one watch by code."""
|
|
21
|
-
return await self._one(WatchOut, "GET", f"/pipelines/{pipeline}/triggers/watches/{code}")
|
|
22
|
-
|
|
23
|
-
async def pause(self, pipeline: str, code: str) -> WatchOut:
|
|
24
|
-
"""Stop a watch, cancelling the run it has waiting, and keep where it left off."""
|
|
25
|
-
return await self._one(WatchOut, "POST", f"/pipelines/{pipeline}/triggers/watches/{code}/$pause")
|
|
26
|
-
|
|
27
|
-
async def resume(self, pipeline: str, code: str) -> WatchOut:
|
|
28
|
-
"""Start a watch again, arming a run from where its last success left off."""
|
|
29
|
-
return await self._one(WatchOut, "POST", f"/pipelines/{pipeline}/triggers/watches/{code}/$resume")
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
"""A pipeline's inbound webhooks: their mapping, their token, and what has arrived."""
|
|
2
|
-
|
|
3
|
-
from pydantic import SecretStr
|
|
4
|
-
|
|
5
|
-
from dirigent_client.enums import RunPriority
|
|
6
|
-
from dirigent_client.resources.base import Resource, query, request_body
|
|
7
|
-
from dirigent_client.schemas import DeliveryOut, Page, WebhookIn, WebhookOut, WebhookTokenOut
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class Webhooks(Resource):
|
|
11
|
-
"""Declare, enable, rotate, and read the webhooks hanging from a pipeline."""
|
|
12
|
-
|
|
13
|
-
async def list(self, pipeline: str, *, after: str | None = None, limit: int | None = None) -> Page[WebhookOut]:
|
|
14
|
-
"""List every webhook on a pipeline, with its mapping but never its token."""
|
|
15
|
-
return await self._many(
|
|
16
|
-
WebhookOut,
|
|
17
|
-
"GET",
|
|
18
|
-
f"/pipelines/{pipeline}/triggers/webhooks",
|
|
19
|
-
params=query(after=after, limit=limit),
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
async def get(self, pipeline: str, code: str) -> WebhookOut:
|
|
23
|
-
"""Read one webhook by code, with its mapping but never its token."""
|
|
24
|
-
return await self._one(WebhookOut, "GET", f"/pipelines/{pipeline}/triggers/webhooks/{code}")
|
|
25
|
-
|
|
26
|
-
async def create(
|
|
27
|
-
self,
|
|
28
|
-
pipeline: str,
|
|
29
|
-
code: str,
|
|
30
|
-
*,
|
|
31
|
-
name: str | None = None,
|
|
32
|
-
description: str | None = None,
|
|
33
|
-
params_from_payload: dict[str, str] | None = None,
|
|
34
|
-
hmac_secret: str | None = None,
|
|
35
|
-
rate_limit_per_minute: int = 60,
|
|
36
|
-
priority: RunPriority | None = None,
|
|
37
|
-
) -> WebhookTokenOut:
|
|
38
|
-
"""Declare a webhook and return its token, which is shown here and nowhere else again."""
|
|
39
|
-
payload = WebhookIn(
|
|
40
|
-
code=code,
|
|
41
|
-
name=name,
|
|
42
|
-
description=description,
|
|
43
|
-
params_from_payload=params_from_payload or {},
|
|
44
|
-
hmac_secret=SecretStr(hmac_secret) if hmac_secret else None,
|
|
45
|
-
rate_limit_per_minute=rate_limit_per_minute,
|
|
46
|
-
priority=priority,
|
|
47
|
-
)
|
|
48
|
-
return await self._one(
|
|
49
|
-
WebhookTokenOut,
|
|
50
|
-
"POST",
|
|
51
|
-
f"/pipelines/{pipeline}/triggers/webhooks",
|
|
52
|
-
json=request_body(payload),
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
async def rotate_token(self, pipeline: str, code: str) -> WebhookTokenOut:
|
|
56
|
-
"""Mint a new token and forget the old one immediately; callers must be updated."""
|
|
57
|
-
return await self._one(WebhookTokenOut, "POST", f"/pipelines/{pipeline}/triggers/webhooks/{code}/$rotate-token")
|
|
58
|
-
|
|
59
|
-
async def enable(self, pipeline: str, code: str) -> WebhookOut:
|
|
60
|
-
"""Accept deliveries again on the token that was already issued."""
|
|
61
|
-
return await self._one(WebhookOut, "POST", f"/pipelines/{pipeline}/triggers/webhooks/{code}/$enable")
|
|
62
|
-
|
|
63
|
-
async def disable(self, pipeline: str, code: str) -> WebhookOut:
|
|
64
|
-
"""Refuse deliveries without rotating or losing the token."""
|
|
65
|
-
return await self._one(WebhookOut, "POST", f"/pipelines/{pipeline}/triggers/webhooks/{code}/$disable")
|
|
66
|
-
|
|
67
|
-
async def delete(self, pipeline: str, code: str) -> None:
|
|
68
|
-
"""Remove a webhook, its token, and its delivery history."""
|
|
69
|
-
await self._transport.request("DELETE", f"/pipelines/{pipeline}/triggers/webhooks/{code}")
|
|
70
|
-
|
|
71
|
-
async def deliveries(
|
|
72
|
-
self, pipeline: str, code: str, *, after: str | None = None, limit: int | None = None
|
|
73
|
-
) -> Page[DeliveryOut]:
|
|
74
|
-
"""Read what has arrived, newest first, refusals included."""
|
|
75
|
-
return await self._many(
|
|
76
|
-
DeliveryOut,
|
|
77
|
-
"GET",
|
|
78
|
-
f"/pipelines/{pipeline}/triggers/webhooks/{code}/deliveries",
|
|
79
|
-
params=query(after=after, limit=limit),
|
|
80
|
-
)
|
|
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_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/connections.py
RENAMED
|
File without changes
|
|
File without changes
|
{dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/pipelines.py
RENAMED
|
File without changes
|
|
File without changes
|
{dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/resources/schedules.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dirigent_client-0.26.0 → dirigent_client-0.27.0}/src/dirigent_client/schemas/connections.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|