33Provides normalization and helper functions for job status tracking.
44"""
55
6+ from typing import Optional
7+
68from comfy_api .internal import prune_dict
79
810
@@ -23,7 +25,19 @@ class JobStatus:
2325THREE_D_EXTENSIONS = frozenset ({'.obj' , '.fbx' , '.gltf' , '.glb' })
2426
2527
26- def is_previewable (media_type , item ):
28+ def _extract_job_metadata (extra_data : dict ) -> tuple [Optional [int ], Optional [str ]]:
29+ """Extract create_time and workflow_id from extra_data.
30+
31+ Returns:
32+ tuple: (create_time, workflow_id)
33+ """
34+ create_time = extra_data .get ('create_time' )
35+ extra_pnginfo = extra_data .get ('extra_pnginfo' , {})
36+ workflow_id = extra_pnginfo .get ('workflow' , {}).get ('id' )
37+ return create_time , workflow_id
38+
39+
40+ def is_previewable (media_type : str , item : dict ) -> bool :
2741 """
2842 Check if an output item is previewable.
2943 Matches frontend logic in ComfyUI_frontend/src/stores/queueStore.ts
@@ -49,12 +63,10 @@ def is_previewable(media_type, item):
4963 return False
5064
5165
52- def normalize_queue_item (item , status ) :
66+ def normalize_queue_item (item : tuple , status : str ) -> dict :
5367 """Convert queue item tuple to unified job dict."""
5468 priority , prompt_id , _ , extra_data , _ = item [:5 ]
55- create_time = extra_data .get ('create_time' )
56- extra_pnginfo = extra_data .get ('extra_pnginfo' ) or {}
57- workflow_id = extra_pnginfo .get ('workflow' , {}).get ('id' )
69+ create_time , workflow_id = _extract_job_metadata (extra_data )
5870
5971 return prune_dict ({
6072 'id' : prompt_id ,
@@ -66,13 +78,11 @@ def normalize_queue_item(item, status):
6678 })
6779
6880
69- def normalize_history_item (prompt_id , history_item , include_outputs = False ):
81+ def normalize_history_item (prompt_id : str , history_item : dict , include_outputs : bool = False ) -> dict :
7082 """Convert history item dict to unified job dict."""
7183 prompt_tuple = history_item ['prompt' ]
7284 priority , _ , prompt , extra_data , _ = prompt_tuple [:5 ]
73- create_time = extra_data .get ('create_time' )
74- extra_pnginfo = extra_data .get ('extra_pnginfo' ) or {}
75- workflow_id = extra_pnginfo .get ('workflow' , {}).get ('id' )
85+ create_time , workflow_id = _extract_job_metadata (extra_data )
7686
7787 status_info = history_item .get ('status' , {})
7888 status_str = status_info .get ('status_str' ) if status_info else None
@@ -83,7 +93,7 @@ def normalize_history_item(prompt_id, history_item, include_outputs=False):
8393 else :
8494 status = JobStatus .COMPLETED
8595
86- outputs = history_item .get ('outputs' ) or {}
96+ outputs = history_item .get ('outputs' , {})
8797 outputs_count , preview_output = get_outputs_summary (outputs )
8898
8999 execution_error = None
@@ -126,7 +136,7 @@ def normalize_history_item(prompt_id, history_item, include_outputs=False):
126136 return job
127137
128138
129- def get_outputs_summary (outputs ) :
139+ def get_outputs_summary (outputs : dict ) -> tuple [ int , Optional [ dict ]] :
130140 """
131141 Count outputs and find preview in a single pass.
132142 Returns (outputs_count, preview_output).
@@ -165,23 +175,23 @@ def get_outputs_summary(outputs):
165175 return count , preview_output or fallback_preview
166176
167177
168- def apply_sorting (jobs , sort_by , sort_order ) :
178+ def apply_sorting (jobs : list [ dict ] , sort_by : str , sort_order : str ) -> list [ dict ] :
169179 """Sort jobs list by specified field and order."""
170180 reverse = (sort_order == 'desc' )
171181
172182 if sort_by == 'execution_duration' :
173183 def get_sort_key (job ):
174- start = job .get ('execution_start_time' ) or 0
175- end = job .get ('execution_end_time' ) or 0
184+ start = job .get ('execution_start_time' , 0 )
185+ end = job .get ('execution_end_time' , 0 )
176186 return end - start if end and start else 0
177187 else :
178188 def get_sort_key (job ):
179- return job .get ('create_time' ) or 0
189+ return job .get ('create_time' , 0 )
180190
181191 return sorted (jobs , key = get_sort_key , reverse = reverse )
182192
183193
184- def get_job (prompt_id , running , queued , history ) :
194+ def get_job (prompt_id : str , running : list , queued : list , history : dict ) -> Optional [ dict ] :
185195 """
186196 Get a single job by prompt_id from history or queue.
187197
@@ -208,7 +218,17 @@ def get_job(prompt_id, running, queued, history):
208218 return None
209219
210220
211- def get_all_jobs (running , queued , history , status_filter = None , workflow_id = None , sort_by = "created_at" , sort_order = "desc" , limit = None , offset = 0 ):
221+ def get_all_jobs (
222+ running : list ,
223+ queued : list ,
224+ history : dict ,
225+ status_filter : Optional [list [str ]] = None ,
226+ workflow_id : Optional [str ] = None ,
227+ sort_by : str = "created_at" ,
228+ sort_order : str = "desc" ,
229+ limit : Optional [int ] = None ,
230+ offset : int = 0
231+ ) -> tuple [list [dict ], int ]:
212232 """
213233 Get all jobs (running, pending, completed) with filtering and sorting.
214234
0 commit comments