Skip to content

Commit 5014f69

Browse files
committed
feat: API pipeline run list has execution summary
1 parent 5ae141c commit 5014f69

File tree

2 files changed

+36
-22
lines changed

2 files changed

+36
-22
lines changed

cloud_pipelines_backend/api_server_sql.py

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,22 @@ def _get_current_time() -> datetime.datetime:
3232
from .errors import ItemNotFoundError
3333

3434

35+
@dataclasses.dataclass(kw_only=True)
36+
class ExecutionStatusSummary:
37+
total_executions: int = 0
38+
ended_executions: int = 0
39+
has_ended: bool = False
40+
41+
def count_execution_status(
42+
self, *, status: bts.ContainerExecutionStatus, count: int
43+
) -> None:
44+
self.total_executions += count
45+
if status in bts.CONTAINER_STATUSES_ENDED:
46+
self.ended_executions += count
47+
48+
self.has_ended = self.ended_executions == self.total_executions
49+
50+
3551
# ==== PipelineJobService
3652
@dataclasses.dataclass(kw_only=True)
3753
class PipelineRunResponse:
@@ -43,6 +59,7 @@ class PipelineRunResponse:
4359
created_at: datetime.datetime | None = None
4460
pipeline_name: str | None = None
4561
execution_status_stats: dict[str, int] | None = None
62+
execution_summary: ExecutionStatusSummary | None = None
4663

4764
@classmethod
4865
def from_db(cls, pipeline_run: bts.PipelineRun) -> "PipelineRunResponse":
@@ -241,10 +258,12 @@ def create_pipeline_run_response(
241258
pipeline_name = component_spec.name
242259
response.pipeline_name = pipeline_name
243260
if include_execution_stats:
244-
response.execution_status_stats = self._get_execution_status_stats(
261+
stats, summary = self._get_execution_stats_and_summary(
245262
session=session,
246263
root_execution_id=pipeline_run.root_execution_id,
247264
)
265+
response.execution_status_stats = stats
266+
response.execution_summary = summary
248267
return response
249268

250269
return ListPipelineJobsResponse(
@@ -255,15 +274,20 @@ def create_pipeline_run_response(
255274
next_page_token=next_page_token,
256275
)
257276

258-
def _get_execution_status_stats(
277+
def _get_execution_stats_and_summary(
259278
self,
260279
session: orm.Session,
261280
root_execution_id: bts.IdType,
262-
) -> dict[str, int]:
281+
) -> tuple[dict[str, int], ExecutionStatusSummary]:
263282
stats = self._calculate_execution_status_stats(
264283
session=session, root_execution_id=root_execution_id
265284
)
266-
return {status.value: count for status, count in stats.items()}
285+
summary = ExecutionStatusSummary()
286+
status_stats: dict[str, int] = {}
287+
for status, count in stats.items():
288+
summary.count_execution_status(status=status, count=count)
289+
status_stats[status.value] = count
290+
return status_stats, summary
267291

268292
def _calculate_execution_status_stats(
269293
self, session: orm.Session, root_execution_id: bts.IdType
@@ -482,22 +506,6 @@ class ArtifactNodeIdResponse:
482506
id: bts.IdType
483507

484508

485-
@dataclasses.dataclass(kw_only=True)
486-
class ExecutionStatusSummary:
487-
total_executions: int = 0
488-
ended_executions: int = 0
489-
has_ended: bool = False
490-
491-
def count_execution_status(
492-
self, *, status: bts.ContainerExecutionStatus, count: int
493-
) -> None:
494-
self.total_executions += count
495-
if status in bts.CONTAINER_STATUSES_ENDED:
496-
self.ended_executions += count
497-
498-
self.has_ended = self.ended_executions == self.total_executions
499-
500-
501509
@dataclasses.dataclass
502510
class GetGraphExecutionStateResponse:
503511
child_execution_status_stats: dict[bts.IdType, dict[str, int]]

tests/test_api_server_sql.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,14 @@ def test_list_with_execution_stats(self):
151151
with session_factory() as session:
152152
result = service.list(session=session, include_execution_stats=True)
153153
assert len(result.pipeline_runs) == 1
154-
assert result.pipeline_runs[0].root_execution_id == root_id
155-
stats = result.pipeline_runs[0].execution_status_stats
154+
run = result.pipeline_runs[0]
155+
assert run.root_execution_id == root_id
156+
stats = run.execution_status_stats
156157
assert stats is not None
157158
assert stats["SUCCEEDED"] == 1
158159
assert stats["RUNNING"] == 1
160+
summary = run.execution_summary
161+
assert summary is not None
162+
assert summary.total_executions == 2
163+
assert summary.ended_executions == 1
164+
assert summary.has_ended is False

0 commit comments

Comments
 (0)