3030import psutil
3131
3232from simvue .api .objects .alert .fetch import Alert
33- from simvue .api .objects .folder import Folder , get_folder_from_path
34- from simvue .exception import ObjectNotFoundError , SimvueRunError
33+ from simvue .api .objects .folder import Folder
34+ from simvue .exception import SimvueRunError
3535from simvue .utilities import prettify_pydantic
3636
3737
@@ -184,9 +184,13 @@ def __init__(
184184 if self ._user_config .metrics .resources_metrics_interval < 1
185185 else self ._user_config .metrics .resources_metrics_interval
186186 )
187- self ._headers : dict [str , str ] = {
188- "Authorization" : f"Bearer { self ._user_config .server .token .get_secret_value ()} "
189- }
187+ self ._headers : dict [str , str ] = (
188+ {
189+ "Authorization" : f"Bearer { self ._user_config .server .token .get_secret_value ()} "
190+ }
191+ if mode != "offline"
192+ else {}
193+ )
190194 self ._sv_obj : RunObject | None = None
191195 self ._pid : int | None = 0
192196 self ._shutdown_event : threading .Event | None = None
@@ -411,7 +415,9 @@ def _create_dispatch_callback(
411415 if self ._user_config .run .mode == "online" and not self ._id :
412416 raise RuntimeError ("Expected identifier for run" )
413417
414- if not self ._user_config .server .url or not self ._sv_obj :
418+ if (
419+ self ._user_config .run .mode != "offline" and not self ._user_config .server .url
420+ ) or not self ._sv_obj :
415421 raise RuntimeError ("Cannot commence dispatch, run not initialised" )
416422
417423 def _dispatch_callback (
@@ -459,7 +465,7 @@ def _start(self, reconnect: bool = False) -> bool:
459465
460466 self ._start_time = time .time ()
461467
462- if self ._sv_obj :
468+ if self ._sv_obj and self . _sv_obj . status != "running" :
463469 self ._sv_obj .status = self ._status
464470 self ._sv_obj .started = self ._start_time
465471 self ._sv_obj .commit ()
@@ -558,6 +564,7 @@ def init(
558564 folder : typing .Annotated [
559565 str , pydantic .Field (None , pattern = FOLDER_REGEX )
560566 ] = None ,
567+ notification : typing .Literal ["none" , "all" , "error" , "lost" ] = "none" ,
561568 running : bool = True ,
562569 retention_period : str | None = None ,
563570 timeout : int | None = 180 ,
@@ -579,6 +586,9 @@ def init(
579586 description of the run, by default None
580587 folder : str, optional
581588 folder within which to store the run, by default "/"
589+ notification: typing.Literal["none", "all", "error", "lost"], optional
590+ whether to notify the user by email upon completion of the run if
591+ the run is in the specified state, by default "none"
582592 running : bool, optional
583593 whether to set the status as running or created, the latter implying
584594 the run will be commenced at a later time. Default is True.
@@ -614,13 +624,10 @@ def init(
614624
615625 self ._term_color = not no_color
616626
617- try :
618- self ._folder = get_folder_from_path (path = folder )
619- except ObjectNotFoundError :
620- self ._folder = Folder .new (
621- path = folder , offline = self ._user_config .run .mode == "offline"
622- )
623- self ._folder .commit () # type: ignore
627+ self ._folder = Folder .new (
628+ path = folder , offline = self ._user_config .run .mode == "offline"
629+ )
630+ self ._folder .commit () # type: ignore
624631
625632 if isinstance (visibility , str ) and visibility not in ("public" , "tenant" ):
626633 self ._error (
@@ -631,7 +638,9 @@ def init(
631638 self ._error ("invalid mode specified, must be online, offline or disabled" )
632639 return False
633640
634- if not self ._user_config .server .token or not self ._user_config .server .url :
641+ if self ._user_config .run .mode != "offline" and (
642+ not self ._user_config .server .token or not self ._user_config .server .url
643+ ):
635644 self ._error (
636645 "Unable to get URL and token from environment variables or config file"
637646 )
@@ -683,6 +692,7 @@ def init(
683692 self ._sv_obj .heartbeat_timeout = timeout
684693 self ._sv_obj .alerts = []
685694 self ._sv_obj .created = time .time ()
695+ self ._sv_obj .notifications = notification
686696
687697 if self ._status == "running" :
688698 self ._sv_obj .system = get_system ()
0 commit comments