5757Input and output result groups may only contain, letters, numbers and underscores.
5858"""
5959
60+ LogLevel = Literal ["text" , "warning" , "error" ]
61+ """
62+ Severity level for job event logs.
63+ """
64+
6065
6166class JobController (Controller [Job ]):
6267 """
@@ -108,6 +113,15 @@ class JobController(Controller[Job]):
108113 Project unique ID, e.g., "P3"
109114 """
110115
116+ _events : Dict [str , str ]
117+ """
118+ Named event logs. Key can be user-provided name in log() method, or ID if
119+ name not provided. If both name and ID are used, can have two keys with
120+ the same value.
121+
122+ :meta private:
123+ """
124+
111125 def __init__ (self , cs : "CryoSPARC" , job : Union [Tuple [str , str ], Job ]) -> None :
112126 self .cs = cs
113127 if isinstance (job , tuple ):
@@ -117,6 +131,7 @@ def __init__(self, cs: "CryoSPARC", job: Union[Tuple[str, str], Job]) -> None:
117131 self .project_uid = job .project_uid
118132 self .uid = job .uid
119133 self .model = job
134+ self ._events = {}
120135
121136 @property
122137 def type (self ) -> str :
@@ -526,24 +541,65 @@ def load_output(self, name: str, slots: LoadableSlots = "all", version: Union[in
526541 """
527542 return self .cs .api .jobs .load_output (self .project_uid , self .uid , name , slots = slots , version = version )
528543
529- def log (self , text : str , level : Literal ["text" , "warning" , "error" ] = "text" ):
544+ @overload
545+ def log (self , text : str , * , level : LogLevel = ...) -> str : ...
546+ @overload
547+ def log (self , text : str , * , level : LogLevel = ..., name : str ) -> str : ...
548+ @overload
549+ def log (self , text : str , * , level : LogLevel = ..., id : str ) -> str : ...
550+ def log (self , text : str , * , level : LogLevel = "text" , name : Optional [str ] = None , id : Optional [str ] = None ) -> str :
530551 """
531- Append to a job's event log.
552+ Append to a job's event log. Update an existing log by providing a name
553+ or ID.
532554
533555 Args:
534556 text (str): Text to log
535557 level (str, optional): Log level ("text", "warning" or "error").
536558 Defaults to "text".
559+ name (str, optional): Event name. If called multiple times with the
560+ same name, updates that event instead of creating a new one.
561+ Named events are reset when logging a checkpoint. Cannot be
562+ provided with id. Defaults to None.
563+ id (str, optional): Update a previously-created event log by its ID.
564+ Cannot be provided with name. Defaults to None.
565+
566+ Example:
567+
568+ Log a warning message to the job log.
569+ >>> job.log("This is a warning", level="warning")
570+
571+ Show a live progress bar in the job log.
572+ >>> for pct in range(1, 10):
573+ ... # example log: "Progress: [#####-----] 50%"
574+ ... job.log(f"Progress: [{'#' * pct}{'-' * (10 - pct)}] {pct * 10}%", name="progress")
575+ ... sleep(1)
576+ ...
577+ >>> job.log("Done!")
578+
579+ Update an existing log event by ID.
580+ >>> event_id = job.log("Starting job processing...")
581+ >>> # do some processing...
582+ >>> job.log("Finished processing", id=event_id)
537583
538584 Returns:
539585 str: Created log event ID
540586 """
541- event = self .cs .api .jobs .add_event_log (self .project_uid , self .uid , text , type = level )
587+ existing_id = id
588+ if name and name in self ._events :
589+ existing_id = self ._events [name ]
590+
591+ if existing_id :
592+ event = self .cs .api .jobs .update_event_log (self .project_uid , self .uid , existing_id , text , type = level )
593+ else :
594+ event = self .cs .api .jobs .add_event_log (self .project_uid , self .uid , text , type = level )
595+
596+ if name :
597+ self ._events [name ] = event .id
542598 return event .id
543599
544600 def log_checkpoint (self , meta : dict = {}):
545601 """
546- Append a checkpoint to the job's event log.
602+ Append a checkpoint to the job's event log. Also resets named events.
547603
548604 Args:
549605 meta (dict, optional): Additional meta information. Defaults to {}.
@@ -552,6 +608,7 @@ def log_checkpoint(self, meta: dict = {}):
552608 str: Created checkpoint event ID
553609 """
554610 event = self .cs .api .jobs .add_checkpoint (self .project_uid , self .uid , meta )
611+ self ._events = {}
555612 return event .id
556613
557614 def log_plot (
0 commit comments