interloper-api 0.67.0__tar.gz → 0.69.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.
- {interloper_api-0.67.0 → interloper_api-0.69.0}/PKG-INFO +1 -1
- {interloper_api-0.67.0 → interloper_api-0.69.0}/pyproject.toml +1 -1
- {interloper_api-0.67.0 → interloper_api-0.69.0}/pyproject.toml.orig +1 -1
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/routes/backfills.py +13 -2
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/routes/runs.py +31 -21
- {interloper_api-0.67.0 → interloper_api-0.69.0}/README.md +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/__init__.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/app.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/dependencies/__init__.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/dependencies/auth.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/dependencies/rbac.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/dependencies/state.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/notifications/__init__.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/notifications/invitations.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/routes/__init__.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/routes/admin.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/routes/agent.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/routes/auth.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/routes/catalog.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/routes/components.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/routes/health.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/routes/oauth.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/routes/organisations.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/routes/tokens.py +0 -0
- {interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/routes/websocket.py +0 -0
|
@@ -36,11 +36,19 @@ class BackfillCreateRequest(BaseModel):
|
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
class BackfillResponse(BaseModel):
|
|
39
|
-
"""Response body for a backfill.
|
|
39
|
+
"""Response body for a backfill.
|
|
40
|
+
|
|
41
|
+
The target component's identity is resolved server-side, same contract
|
|
42
|
+
as ``RunResponse``: the ``component_*`` identity fields are ``None``
|
|
43
|
+
exactly when the target was deleted.
|
|
44
|
+
"""
|
|
40
45
|
|
|
41
46
|
id: UUID
|
|
42
47
|
org_id: UUID
|
|
43
48
|
component_id: UUID | None
|
|
49
|
+
component_kind: str | None = None
|
|
50
|
+
component_key: str | None = None
|
|
51
|
+
component_name: str | None = None
|
|
44
52
|
status: str
|
|
45
53
|
start_key: str
|
|
46
54
|
end_key: str
|
|
@@ -56,7 +64,7 @@ class BackfillResponse(BaseModel):
|
|
|
56
64
|
"""Convert a DB Backfill to a BackfillResponse.
|
|
57
65
|
|
|
58
66
|
Args:
|
|
59
|
-
backfill: The DB Backfill row.
|
|
67
|
+
backfill: The DB Backfill row, with its ``target`` relationship loaded.
|
|
60
68
|
|
|
61
69
|
Returns:
|
|
62
70
|
The response model.
|
|
@@ -65,6 +73,9 @@ class BackfillResponse(BaseModel):
|
|
|
65
73
|
id=backfill.id,
|
|
66
74
|
org_id=backfill.org_id,
|
|
67
75
|
component_id=backfill.component_id,
|
|
76
|
+
component_kind=backfill.target.kind if backfill.target else None,
|
|
77
|
+
component_key=backfill.target.key if backfill.target else None,
|
|
78
|
+
component_name=backfill.target.name if backfill.target else None,
|
|
68
79
|
status=backfill.status,
|
|
69
80
|
start_key=backfill.start_key,
|
|
70
81
|
end_key=backfill.end_key,
|
|
@@ -7,7 +7,6 @@ from typing import Annotated, Literal
|
|
|
7
7
|
from uuid import UUID
|
|
8
8
|
|
|
9
9
|
from fastapi import APIRouter, Depends, HTTPException, Query, Response
|
|
10
|
-
from interloper.component import KINDS
|
|
11
10
|
from interloper.errors import NotFoundError
|
|
12
11
|
from interloper_db import Profile, Store
|
|
13
12
|
from interloper_db.models import Event, Run
|
|
@@ -34,11 +33,21 @@ MAX_EVENTS_PAGE_SIZE = 1000
|
|
|
34
33
|
|
|
35
34
|
|
|
36
35
|
class RunResponse(BaseModel):
|
|
37
|
-
"""Response body for a run.
|
|
36
|
+
"""Response body for a run.
|
|
37
|
+
|
|
38
|
+
The target component's identity is resolved server-side (the row is
|
|
39
|
+
eagerly joined), so clients never need a second lookup — including for
|
|
40
|
+
target kinds they do not know about. All three ``component_*`` identity
|
|
41
|
+
fields are ``None`` exactly when the target was deleted
|
|
42
|
+
(``component_id`` nulls on deletion).
|
|
43
|
+
"""
|
|
38
44
|
|
|
39
45
|
id: UUID
|
|
40
46
|
org_id: UUID
|
|
41
47
|
component_id: UUID | None
|
|
48
|
+
component_kind: str | None = None
|
|
49
|
+
component_key: str | None = None
|
|
50
|
+
component_name: str | None = None
|
|
42
51
|
backfill_id: UUID | None
|
|
43
52
|
partition_key: str | None
|
|
44
53
|
status: str
|
|
@@ -54,7 +63,7 @@ class RunResponse(BaseModel):
|
|
|
54
63
|
"""Convert a DB Run to a RunResponse.
|
|
55
64
|
|
|
56
65
|
Args:
|
|
57
|
-
run: The DB Run row.
|
|
66
|
+
run: The DB Run row, with its ``target`` relationship loaded.
|
|
58
67
|
|
|
59
68
|
Returns:
|
|
60
69
|
The response model.
|
|
@@ -63,6 +72,9 @@ class RunResponse(BaseModel):
|
|
|
63
72
|
id=run.id,
|
|
64
73
|
org_id=run.org_id,
|
|
65
74
|
component_id=run.component_id,
|
|
75
|
+
component_kind=run.target.kind if run.target else None,
|
|
76
|
+
component_key=run.target.key if run.target else None,
|
|
77
|
+
component_name=run.target.name if run.target else None,
|
|
66
78
|
backfill_id=run.backfill_id,
|
|
67
79
|
partition_key=run.partition_key,
|
|
68
80
|
status=run.status,
|
|
@@ -88,13 +100,13 @@ class RetryRequest(BaseModel):
|
|
|
88
100
|
scope: Literal["all", "failed"] = "all"
|
|
89
101
|
|
|
90
102
|
|
|
91
|
-
class
|
|
92
|
-
"""Response body for an
|
|
103
|
+
class ExecutionResponse(BaseModel):
|
|
104
|
+
"""Response body for an operation execution (from the ``executions`` view)."""
|
|
93
105
|
|
|
94
106
|
run_id: UUID
|
|
95
107
|
org_id: UUID
|
|
96
|
-
|
|
97
|
-
|
|
108
|
+
component_id: UUID | None = None
|
|
109
|
+
component_key: str
|
|
98
110
|
status: str
|
|
99
111
|
started_at: str | None = None
|
|
100
112
|
completed_at: str | None = None
|
|
@@ -238,7 +250,7 @@ def create_run(
|
|
|
238
250
|
user: Profile = Depends(get_current_user),
|
|
239
251
|
store: Store = Depends(get_store),
|
|
240
252
|
) -> RunResponse:
|
|
241
|
-
"""Queue a single run targeting a
|
|
253
|
+
"""Queue a single run targeting a component whose kind declares an operation.
|
|
242
254
|
|
|
243
255
|
Args:
|
|
244
256
|
body: The component to run and the partition key to run it for.
|
|
@@ -249,12 +261,10 @@ def create_run(
|
|
|
249
261
|
The queued run, as a response model.
|
|
250
262
|
|
|
251
263
|
Raises:
|
|
252
|
-
HTTPException: 400 if the
|
|
253
|
-
|
|
264
|
+
HTTPException: 400 if the store rejects the run (a kind with no
|
|
265
|
+
operation, or an invalid partition key).
|
|
254
266
|
"""
|
|
255
267
|
target = load_authorized(store.components.get, body.component_id, user, store, label="Component", minimum="editor")
|
|
256
|
-
if not KINDS[target.kind].runnable:
|
|
257
|
-
raise HTTPException(status_code=400, detail=f"Components of kind '{target.kind}' cannot be run")
|
|
258
268
|
try:
|
|
259
269
|
run = store.runs.create(target.org_id, component_id=body.component_id, partition_key=body.partition_key)
|
|
260
270
|
except ValueError as e:
|
|
@@ -282,13 +292,13 @@ def get_run(
|
|
|
282
292
|
return RunResponse.from_run(run)
|
|
283
293
|
|
|
284
294
|
|
|
285
|
-
@router.get("/{run_id}/
|
|
286
|
-
def
|
|
295
|
+
@router.get("/{run_id}/executions")
|
|
296
|
+
def list_executions(
|
|
287
297
|
run_id: UUID,
|
|
288
298
|
user: Profile = Depends(get_current_user),
|
|
289
299
|
store: Store = Depends(get_store),
|
|
290
|
-
) -> list[
|
|
291
|
-
"""List
|
|
300
|
+
) -> list[ExecutionResponse]:
|
|
301
|
+
"""List operation executions for a run.
|
|
292
302
|
|
|
293
303
|
Args:
|
|
294
304
|
run_id: The run UUID.
|
|
@@ -296,16 +306,16 @@ def list_asset_executions(
|
|
|
296
306
|
store: The Store instance.
|
|
297
307
|
|
|
298
308
|
Returns:
|
|
299
|
-
The run's
|
|
309
|
+
The run's operation executions, as response models.
|
|
300
310
|
"""
|
|
301
311
|
_load_authorized_run(run_id, user, store)
|
|
302
|
-
rows = store.events.
|
|
312
|
+
rows = store.events.list_executions(run_id)
|
|
303
313
|
return [
|
|
304
|
-
|
|
314
|
+
ExecutionResponse(
|
|
305
315
|
run_id=row.run_id,
|
|
306
316
|
org_id=row.org_id,
|
|
307
|
-
|
|
308
|
-
|
|
317
|
+
component_id=row.component_id,
|
|
318
|
+
component_key=row.component_key or "",
|
|
309
319
|
status=row.status,
|
|
310
320
|
started_at=str(row.started_at) if row.started_at else None,
|
|
311
321
|
completed_at=str(row.completed_at) if row.completed_at else None,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/notifications/__init__.py
RENAMED
|
File without changes
|
{interloper_api-0.67.0 → interloper_api-0.69.0}/src/interloper_api/notifications/invitations.py
RENAMED
|
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
|