-
Notifications
You must be signed in to change notification settings - Fork 70
FXC-4925: Remove BatchDetail and BatchTask in webapi #3183
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -40,8 +40,7 @@ | |||||||||||||||||
| TaskId, | ||||||||||||||||||
| ) | ||||||||||||||||||
| from tidy3d.web.core.task_core import ( | ||||||||||||||||||
| BatchDetail, | ||||||||||||||||||
| BatchTask, | ||||||||||||||||||
| BatchTask, # noqa: F401 - Deprecated alias, kept for backward compatibility | ||||||||||||||||||
| Folder, | ||||||||||||||||||
| SimulationTask, | ||||||||||||||||||
| TaskFactory, | ||||||||||||||||||
|
|
@@ -116,8 +115,8 @@ def _batch_detail_error(resource_id: str) -> Optional[WebError]: | |||||||||||||||||
|
|
||||||||||||||||||
| # TODO: test properly | ||||||||||||||||||
| try: | ||||||||||||||||||
| batch = BatchTask.get(resource_id) | ||||||||||||||||||
| batch_detail = batch.detail() | ||||||||||||||||||
| task = SimulationTask.get(resource_id) | ||||||||||||||||||
| batch_detail = task.detail() | ||||||||||||||||||
| status = batch_detail.status.lower() | ||||||||||||||||||
| except Exception as e: | ||||||||||||||||||
| log.error(f"Could not retrieve batch details for '{resource_id}': {e}") | ||||||||||||||||||
|
|
@@ -619,7 +618,7 @@ def get_reduced_simulation( | |||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
| @wait_for_connection | ||||||||||||||||||
| def get_info(task_id: TaskId, verbose: bool = True) -> TaskInfo | BatchDetail: | ||||||||||||||||||
| def get_info(task_id: TaskId, verbose: bool = True) -> TaskInfo: | ||||||||||||||||||
| """Return information about a simulation task or a modeler batch. | ||||||||||||||||||
|
|
||||||||||||||||||
| This function fetches details for a given task ID, automatically | ||||||||||||||||||
|
|
@@ -635,9 +634,8 @@ def get_info(task_id: TaskId, verbose: bool = True) -> TaskInfo | BatchDetail: | |||||||||||||||||
|
|
||||||||||||||||||
| Returns | ||||||||||||||||||
| ------- | ||||||||||||||||||
| TaskInfo | BatchDetail | ||||||||||||||||||
| A ``TaskInfo`` object for a standard simulation task, or a | ||||||||||||||||||
| ``BatchDetail`` object for a modeler batch. | ||||||||||||||||||
| TaskInfo | ||||||||||||||||||
| An object containing information about the task or batch. | ||||||||||||||||||
|
|
||||||||||||||||||
| Raises | ||||||||||||||||||
| ------ | ||||||||||||||||||
|
|
@@ -714,17 +712,17 @@ def get_run_info(task_id: TaskId) -> tuple[Optional[float], Optional[float]]: | |||||||||||||||||
| Is ``None`` if run info not available. | ||||||||||||||||||
| """ | ||||||||||||||||||
| task = TaskFactory.get(task_id) | ||||||||||||||||||
| if isinstance(task, BatchTask): | ||||||||||||||||||
| if task._is_batch_type(): | ||||||||||||||||||
| raise NotImplementedError("Operation not implemented for modeler batches.") | ||||||||||||||||||
| return task.get_running_info() | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
| def _get_batch_detail_handle_error_status(batch: BatchTask) -> BatchDetail: | ||||||||||||||||||
| def _get_batch_detail_handle_error_status(task: SimulationTask) -> TaskInfo: | ||||||||||||||||||
| """Get batch detail and raise error if status is in ERROR_STATES.""" | ||||||||||||||||||
| detail = batch.detail() | ||||||||||||||||||
| detail = task.detail() | ||||||||||||||||||
| status = detail.status.lower() | ||||||||||||||||||
| if status in ERROR_STATES: | ||||||||||||||||||
| _batch_detail_error(batch.task_id) | ||||||||||||||||||
| _batch_detail_error(task.task_id) | ||||||||||||||||||
| return detail | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
|
|
@@ -737,7 +735,7 @@ def get_status(task_id: TaskId) -> str: | |||||||||||||||||
| Unique identifier of task on server. Returned by :meth:`upload`. | ||||||||||||||||||
| """ | ||||||||||||||||||
| task = TaskFactory.get(task_id) | ||||||||||||||||||
| if isinstance(task, BatchTask): | ||||||||||||||||||
| if task._is_batch_type(): | ||||||||||||||||||
| return _get_batch_detail_handle_error_status(task).status | ||||||||||||||||||
| else: | ||||||||||||||||||
| task_info = get_info(task_id) | ||||||||||||||||||
|
|
@@ -788,7 +786,7 @@ def monitor(task_id: TaskId, verbose: bool = True, worker_group: Optional[str] = | |||||||||||||||||
|
|
||||||||||||||||||
| # Batch/modeler monitoring path | ||||||||||||||||||
| task = TaskFactory.get(task_id) | ||||||||||||||||||
| if isinstance(task, BatchTask): | ||||||||||||||||||
| if task._is_batch_type(): | ||||||||||||||||||
| return _monitor_modeler_batch(task_id, verbose=verbose) | ||||||||||||||||||
|
|
||||||||||||||||||
| console = get_logging_console() if verbose else None | ||||||||||||||||||
|
|
@@ -985,7 +983,7 @@ def download( | |||||||||||||||||
| """ | ||||||||||||||||||
| path = Path(path) | ||||||||||||||||||
| task = TaskFactory.get(task_id, verbose=False) | ||||||||||||||||||
| if isinstance(task, BatchTask): | ||||||||||||||||||
| if task._is_batch_type(): | ||||||||||||||||||
| if path.name == "simulation_data.hdf5": | ||||||||||||||||||
| path = path.with_name("cm_data.hdf5") | ||||||||||||||||||
| task.get_data_hdf5( | ||||||||||||||||||
|
|
@@ -1022,7 +1020,7 @@ def download_json(task_id: TaskId, path: PathLike = SIM_FILE_JSON, verbose: bool | |||||||||||||||||
|
|
||||||||||||||||||
| """ | ||||||||||||||||||
| task = TaskFactory.get(task_id, verbose=False) | ||||||||||||||||||
| if isinstance(task, BatchTask): | ||||||||||||||||||
| if task._is_batch_type(): | ||||||||||||||||||
| raise NotImplementedError("Operation not implemented for modeler batches.") | ||||||||||||||||||
| task.get_simulation_json(path, verbose=verbose) | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
@@ -1055,7 +1053,7 @@ def load_simulation( | |||||||||||||||||
| Simulation loaded from downloaded json file. | ||||||||||||||||||
| """ | ||||||||||||||||||
| task = TaskFactory.get(task_id, verbose=False) | ||||||||||||||||||
| if isinstance(task, BatchTask): | ||||||||||||||||||
| if task._is_batch_type(): | ||||||||||||||||||
| raise NotImplementedError("Operation not implemented for modeler batches.") | ||||||||||||||||||
| path = Path(path) | ||||||||||||||||||
| if path.suffix == ".json": | ||||||||||||||||||
|
|
@@ -1092,7 +1090,7 @@ def download_log( | |||||||||||||||||
| To load downloaded results into data, call :meth:`load` with option ``replace_existing=False``. | ||||||||||||||||||
| """ | ||||||||||||||||||
| task = TaskFactory.get(task_id, verbose=False) | ||||||||||||||||||
| if isinstance(task, BatchTask): | ||||||||||||||||||
| if task._is_batch_type(): | ||||||||||||||||||
| raise NotImplementedError("Operation not implemented for modeler batches.") | ||||||||||||||||||
| task.get_log(path, verbose=verbose, progress_callback=progress_callback) | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
@@ -1145,12 +1143,10 @@ def load( | |||||||||||||||||
| """ | ||||||||||||||||||
| path = Path(path) | ||||||||||||||||||
| task = TaskFactory.get(task_id) if task_id else None | ||||||||||||||||||
| # Check if task is a batch type (handle mocked objects that may not have the method) | ||||||||||||||||||
| is_batch = task is not None and getattr(task, "_is_batch_type", lambda: False)() | ||||||||||||||||||
|
Comment on lines
+1146
to
+1147
|
||||||||||||||||||
| # Check if task is a batch type (handle mocked objects that may not have the method) | |
| is_batch = task is not None and getattr(task, "_is_batch_type", lambda: False)() | |
| if task is not None and not isinstance(task, SimulationTask): | |
| raise TypeError( | |
| f"Expected 'SimulationTask' from TaskFactory.get for task_id={task_id!r}, " | |
| f"got {type(task).__name__!r} instead." | |
| ) | |
| is_batch = bool(task is not None and task._is_batch_type()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calling len() on potentially None tasks field
Medium Severity
The tasks field in TaskInfo defaults to None (changed from [] in the removed BatchDetail class), but _monitor_modeler_batch calls len(detail.tasks) at line 1237 without checking for None first. If the batch API response isn't a dict or the transformation in detail() is bypassed, tasks would be None, causing a TypeError: object of type 'NoneType' has no len().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The BatchTask alias is deprecated and imported with noqa: F401 to suppress unused import warnings. However, this import should be explicitly documented in a docstring or comment explaining the deprecation timeline and migration path for users. Consider adding a deprecation warning when BatchTask is used, or at minimum document when this alias will be removed.