@@ -44,9 +44,9 @@ def _check_path_dir(path: str) -> None:
4444 """Make sure local output directory exists and create it if not."""
4545
4646 @staticmethod
47- def _check_folder (folder_name : str ) -> None :
47+ def _check_folder (folder_name : str ) -> Folder :
4848 """Make sure ``folder_name`` exists on the web UI and create it if not."""
49- Folder .get (folder_name , create = True )
49+ return Folder .get (folder_name , create = True )
5050
5151
5252class Job (WebContainer ):
@@ -235,24 +235,24 @@ def run(self, path: str = DEFAULT_DATA_PATH) -> SimulationDataType:
235235 self .monitor ()
236236 return self .load (path = path )
237237
238- @cached_property
239- def task_id (self ) -> TaskId :
238+ def task_id (self , batch_id : str = None ) -> TaskId :
240239 """The task ID for this ``Job``. Uploads the ``Job`` if it hasn't already been uploaded."""
241240 if self .task_id_cached :
242241 return self .task_id_cached
243242 self ._check_folder (self .folder_name )
244- return self ._upload ()
243+ return self ._upload (batch_id )
245244
246- def _upload (self ) -> TaskId :
245+ def _upload (self , batch_id : str ) -> TaskId :
247246 """Upload this job and return the task ID for handling."""
248247 # upload kwargs with all fields except task_id
249248 upload_kwargs = {key : getattr (self , key ) for key in self ._upload_fields }
249+ upload_kwargs ["batch_id" ] = batch_id
250250 task_id = web .upload (** upload_kwargs )
251251 return task_id
252252
253- def upload (self ) -> None :
253+ def upload (self , batch_id : str = None ) -> None :
254254 """Upload this ``Job``."""
255- _ = self .task_id
255+ _ = self .task_id ( batch_id )
256256
257257 def get_info (self ) -> TaskInfo :
258258 """Return information about a :class:`Job`.
@@ -370,7 +370,9 @@ def estimate_cost(self, verbose: bool = True) -> float:
370370 Cost is calculated assuming the simulation runs for
371371 the full ``run_time``. If early shut-off is triggered, the cost is adjusted proportionately.
372372 """
373- return web .estimate_cost (self .task_id , verbose = verbose , solver_version = self .solver_version )
373+ return web .estimate_cost (
374+ self .task_id (), verbose = verbose , solver_version = self .solver_version
375+ )
374376
375377 @staticmethod
376378 def _check_path_dir (path : str ) -> None :
@@ -511,6 +513,18 @@ class Batch(WebContainer):
511513 description = "Name of folder to store member of each batch on web UI." ,
512514 )
513515
516+ batch_id : str = pd .Field (
517+ None ,
518+ title = "Batch Id" ,
519+ description = "ID of batch to store member of each batch on web UI." ,
520+ )
521+
522+ batch_name : str = pd .Field (
523+ "batch" ,
524+ title = "Batch Name" ,
525+ description = "Name of batch to store member of each batch on web UI." ,
526+ )
527+
514528 verbose : bool = pd .Field (
515529 True , title = "Verbose" , description = "Whether to print info messages and progressbars."
516530 )
@@ -674,8 +688,15 @@ def num_jobs(self) -> int:
674688 def upload (self ) -> None :
675689 """Upload a series of tasks associated with this ``Batch`` using multi-threading."""
676690 self ._check_folder (self .folder_name )
691+ batch_id = self .create_batch ()
677692 with ThreadPoolExecutor (max_workers = self .num_workers ) as executor :
678- futures = [executor .submit (job .upload ) for _ , job in self .jobs .items ()]
693+ futures = [
694+ executor .submit (
695+ job .upload ,
696+ batch_id ,
697+ )
698+ for _ , job in self .jobs .items ()
699+ ]
679700
680701 # progressbar (number of tasks uploaded)
681702 if self .verbose :
@@ -711,6 +732,10 @@ def get_info(self) -> dict[TaskName, TaskInfo]:
711732 def start (self ) -> None :
712733 """Start running all tasks in the :class:`Batch`.
713734
735+ Parameters:
736+ batch_id: str
737+ Batch ID to start the tasks in.
738+
714739 Note
715740 ----
716741 To monitor the running simulations, can call :meth:`Batch.monitor`.
@@ -1068,3 +1093,8 @@ def _check_path_dir(path_dir: str) -> None:
10681093 """
10691094 if len (path_dir ) > 0 and not os .path .exists (path_dir ):
10701095 os .makedirs (path_dir , exist_ok = True )
1096+
1097+ def create_batch (self ) -> str :
1098+ """Create batch."""
1099+ folder = self ._check_folder (self .folder_name )
1100+ return OptimizationBatch .create (self .batch_name , folder .folder_id )
0 commit comments