@@ -32,6 +32,22 @@ def _get_current_time() -> datetime.datetime:
3232from .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 )
3753class 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
502510class GetGraphExecutionStateResponse :
503511 child_execution_status_stats : dict [bts .IdType , dict [str , int ]]
0 commit comments