interloper-api 0.78.0__tar.gz → 0.81.1__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.
Files changed (25) hide show
  1. {interloper_api-0.78.0 → interloper_api-0.81.1}/PKG-INFO +1 -1
  2. {interloper_api-0.78.0 → interloper_api-0.81.1}/pyproject.toml +1 -1
  3. {interloper_api-0.78.0 → interloper_api-0.81.1}/pyproject.toml.orig +1 -1
  4. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/routes/components.py +2 -0
  5. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/routes/runs.py +42 -15
  6. {interloper_api-0.78.0 → interloper_api-0.81.1}/README.md +0 -0
  7. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/__init__.py +0 -0
  8. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/app.py +0 -0
  9. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/dependencies/__init__.py +0 -0
  10. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/dependencies/auth.py +0 -0
  11. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/dependencies/rbac.py +0 -0
  12. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/dependencies/state.py +0 -0
  13. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/notifications/__init__.py +0 -0
  14. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/notifications/invitations.py +0 -0
  15. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/routes/__init__.py +0 -0
  16. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/routes/admin.py +0 -0
  17. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/routes/agent.py +0 -0
  18. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/routes/auth.py +0 -0
  19. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/routes/backfills.py +0 -0
  20. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/routes/catalog.py +0 -0
  21. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/routes/health.py +0 -0
  22. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/routes/oauth.py +0 -0
  23. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/routes/organisations.py +0 -0
  24. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/routes/tokens.py +0 -0
  25. {interloper_api-0.78.0 → interloper_api-0.81.1}/src/interloper_api/routes/websocket.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: interloper-api
3
- Version: 0.78.0
3
+ Version: 0.81.1
4
4
  Summary: Interloper FastAPI routes
5
5
  Author: Guillaume Onfroy
6
6
  Author-email: Guillaume Onfroy <guillaume@digitlcloud.com>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "interloper-api"
3
- version = "0.78.0"
3
+ version = "0.81.1"
4
4
  description = "Interloper FastAPI routes"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -3,7 +3,7 @@
3
3
  # ###############
4
4
  [project]
5
5
  name = "interloper-api"
6
- version = "0.78.0"
6
+ version = "0.81.1"
7
7
  description = "Interloper FastAPI routes"
8
8
  readme = "README.md"
9
9
  authors = [{ name = "Guillaume Onfroy", email = "guillaume@digitlcloud.com" }]
@@ -132,6 +132,7 @@ class ComponentResponse(BaseModel):
132
132
  kind: str
133
133
  key: str
134
134
  name: str | None = None
135
+ discriminator: str | None = None
135
136
  status: ComponentStatus
136
137
  config: dict[str, Any] | None = None
137
138
  state: dict[str, Any] | None = None
@@ -191,6 +192,7 @@ class ComponentResponse(BaseModel):
191
192
  kind=row.kind,
192
193
  key=row.key,
193
194
  name=row.name,
195
+ discriminator=store.components.discriminator(row),
194
196
  status=status,
195
197
  config=config,
196
198
  state=row.state,
@@ -9,7 +9,7 @@ from uuid import UUID
9
9
  from fastapi import APIRouter, HTTPException, Query, Response
10
10
  from interloper.errors import NotFoundError
11
11
  from interloper_db import Profile, Store
12
- from interloper_db.models import Event, Run
12
+ from interloper_db.models import Event, Execution, Run
13
13
  from pydantic import BaseModel
14
14
 
15
15
  from interloper_api.dependencies import (
@@ -112,6 +112,27 @@ class ExecutionResponse(BaseModel):
112
112
  completed_at: str | None = None
113
113
  created_at: str | None = None
114
114
 
115
+ @classmethod
116
+ def from_row(cls, row: Execution) -> ExecutionResponse:
117
+ """Convert an executions-view row to its response model.
118
+
119
+ Args:
120
+ row: The execution row.
121
+
122
+ Returns:
123
+ The response model.
124
+ """
125
+ return cls(
126
+ run_id=row.run_id,
127
+ org_id=row.org_id,
128
+ component_id=row.component_id,
129
+ component_key=row.component_key or "",
130
+ status=row.status,
131
+ started_at=str(row.started_at) if row.started_at else None,
132
+ completed_at=str(row.completed_at) if row.completed_at else None,
133
+ created_at=str(row.created_at) if row.created_at else None,
134
+ )
135
+
115
136
 
116
137
  class EventResponse(BaseModel):
117
138
  """Response body for an event."""
@@ -291,6 +312,25 @@ def create_run(
291
312
  return RunResponse.from_run(run)
292
313
 
293
314
 
315
+ @router.get("/executions/latest")
316
+ def list_latest_executions(
317
+ user: ViewerDep,
318
+ org_id: OrgIdDep,
319
+ store: StoreDep,
320
+ ) -> list[ExecutionResponse]:
321
+ """The latest execution of every asset in the active organisation.
322
+
323
+ Args:
324
+ user: The authenticated user.
325
+ org_id: The active organisation UUID.
326
+ store: The Store instance.
327
+
328
+ Returns:
329
+ One execution per asset that has ever run, as response models.
330
+ """
331
+ return [ExecutionResponse.from_row(row) for row in store.events.latest_executions(org_id)]
332
+
333
+
294
334
  @router.get("/{run_id}")
295
335
  def get_run(
296
336
  run_id: UUID,
@@ -328,20 +368,7 @@ def list_executions(
328
368
  The run's operation executions, as response models.
329
369
  """
330
370
  _load_authorized_run(run_id, user, store)
331
- rows = store.events.list_executions(run_id)
332
- return [
333
- ExecutionResponse(
334
- run_id=row.run_id,
335
- org_id=row.org_id,
336
- component_id=row.component_id,
337
- component_key=row.component_key or "",
338
- status=row.status,
339
- started_at=str(row.started_at) if row.started_at else None,
340
- completed_at=str(row.completed_at) if row.completed_at else None,
341
- created_at=str(row.created_at) if row.created_at else None,
342
- )
343
- for row in rows
344
- ]
371
+ return [ExecutionResponse.from_row(row) for row in store.events.list_executions(run_id)]
345
372
 
346
373
 
347
374
  @router.post("/{run_id}/retry")