Skip to content

Commit a7ef8e9

Browse files
yaugenst-flexmomchil-flex
authored andcommitted
fix: deletion of tasks using web.delete(task_id)
1 parent be3bdbc commit a7ef8e9

File tree

5 files changed

+101
-12
lines changed

5 files changed

+101
-12
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2323
- Bug in handling of tuple-type gradients that could lead to empty tuples or failing gradient calculations when differentiating w.r.t. (for instance) `td.Box.center`.
2424
- Bug causing incorrect field projection results when multiple projection monitors with numerous sampling points were used.
2525
- Improved accuracy for normal E-field components in mode solver at microwave frequencies.
26+
- Deleting tasks using `web.delete(task_id)` would error when deleting tasks in the tidy3d root folder and others would not get completely removed in the Web GUI.
2627

2728
## [2.8.0] - 2025-03-04
2829

tests/test_web/test_webapi.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,39 @@ def mock_download(*args, **kwargs):
342342

343343
@responses.activate
344344
def test_delete(set_api_key, mock_get_info):
345+
responses.add(
346+
responses.GET,
347+
f"{Env.current.web_api_endpoint}/tidy3d/tasks/{TASK_ID}",
348+
json={
349+
"data": {
350+
"taskId": TASK_ID,
351+
"groupId": "group123",
352+
"version": "v1",
353+
"createdAt": CREATED_AT,
354+
}
355+
},
356+
status=200,
357+
)
358+
359+
responses.add(
360+
responses.DELETE,
361+
f"{Env.current.web_api_endpoint}/tidy3d/group/group123/versions",
362+
match=[
363+
matchers.json_params_matcher(
364+
{
365+
"versions": ["v1"],
366+
}
367+
)
368+
],
369+
json={
370+
"data": {
371+
"taskId": TASK_ID,
372+
"createdAt": CREATED_AT,
373+
}
374+
},
375+
status=200,
376+
)
377+
345378
responses.add(
346379
responses.DELETE,
347380
f"{Env.current.web_api_endpoint}/tidy3d/tasks/{TASK_ID}",
@@ -413,13 +446,47 @@ def test_delete_old(set_api_key):
413446
json={"data": {"projectId": TASK_ID, "projectName": PROJECT_NAME}},
414447
status=200,
415448
)
449+
416450
responses.add(
417451
responses.GET,
418452
f"{Env.current.web_api_endpoint}/tidy3d/projects/{TASK_ID}/tasks",
419453
json={"data": [{"taskId": TASK_ID, "createdAt": CREATED_AT}]},
420454
status=200,
421455
)
422456

457+
responses.add(
458+
responses.GET,
459+
f"{Env.current.web_api_endpoint}/tidy3d/tasks/{TASK_ID}",
460+
json={
461+
"data": {
462+
"taskId": TASK_ID,
463+
"groupId": "group123",
464+
"version": "v1",
465+
"createdAt": CREATED_AT,
466+
}
467+
},
468+
status=200,
469+
)
470+
471+
responses.add(
472+
responses.DELETE,
473+
f"{Env.current.web_api_endpoint}/tidy3d/group/group123/versions",
474+
match=[
475+
matchers.json_params_matcher(
476+
{
477+
"versions": ["v1"],
478+
}
479+
)
480+
],
481+
json={
482+
"data": {
483+
"taskId": TASK_ID,
484+
"createdAt": CREATED_AT,
485+
}
486+
},
487+
status=200,
488+
)
489+
423490
responses.add(
424491
responses.DELETE,
425492
f"{Env.current.web_api_endpoint}/tidy3d/tasks/{TASK_ID}",

tidy3d/web/api/webapi.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -815,23 +815,23 @@ def load(
815815

816816

817817
@wait_for_connection
818-
def delete(task_id: TaskId) -> TaskInfo:
818+
def delete(task_id: TaskId, versions: bool = False) -> TaskInfo:
819819
"""Delete server-side data associated with task.
820820
821821
Parameters
822822
----------
823823
task_id : str
824824
Unique identifier of task on server. Returned by :meth:`upload`.
825+
versions : bool = False
826+
If ``True``, delete all versions of the task in the task group. Otherwise, delete only the version associated with the task ID.
825827
826828
Returns
827829
-------
828830
TaskInfo
829831
Object containing information about status, size, credits of task.
830832
"""
831-
832-
# task = SimulationTask.get(task_id)
833833
task = SimulationTask(taskId=task_id)
834-
task.delete()
834+
task.delete(versions=versions)
835835
return TaskInfo(**{"taskId": task.task_id, **task.dict()})
836836

837837

tidy3d/web/core/http_util.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,12 @@ def reinit(self):
178178
REINITIALIZED = True
179179

180180
@http_interceptor
181-
def get(self, path: str, json=None):
181+
def get(self, path: str, json=None, params=None):
182182
"""Get the resource."""
183183
self.reinit()
184-
return self.session.get(url=Env.current.get_real_url(path), auth=api_key_auth, json=json)
184+
return self.session.get(
185+
url=Env.current.get_real_url(path), auth=api_key_auth, json=json, params=params
186+
)
185187

186188
@http_interceptor
187189
def post(self, path: str, json=None):
@@ -198,10 +200,12 @@ def put(self, path: str, json=None, files=None):
198200
)
199201

200202
@http_interceptor
201-
def delete(self, path: str):
203+
def delete(self, path: str, json=None, params=None):
202204
"""Delete the resource."""
203205
self.reinit()
204-
return self.session.delete(Env.current.get_real_url(path), auth=api_key_auth)
206+
return self.session.delete(
207+
Env.current.get_real_url(path), auth=api_key_auth, json=json, params=params
208+
)
205209

206210

207211
http = HttpSessionManager(requests.Session())

tidy3d/web/core/task_core.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def get(cls, folder_name: str, create: bool = False):
6969
"""
7070
folder = FOLDER_CACHE.get(folder_name)
7171
if not folder:
72-
resp = http.get(f"tidy3d/project?projectName={folder_name}")
72+
resp = http.get("tidy3d/project", params={"projectName": folder_name})
7373
if resp:
7474
folder = Folder(**resp)
7575
if create and not folder:
@@ -280,11 +280,28 @@ def get_running_tasks(cls) -> List[SimulationTask]:
280280
return []
281281
return parse_obj_as(List[SimulationTask], resp)
282282

283-
def delete(self):
284-
"""Delete current task from server."""
283+
def delete(self, versions: bool = False):
284+
"""Delete current task from server.
285+
286+
Parameters
287+
----------
288+
versions : bool = False
289+
If ``True``, delete all versions of the task in the task group. Otherwise, delete only the version associated with the current task ID.
290+
"""
285291
if not self.task_id:
286292
raise ValueError("Task id not found.")
287-
http.delete(f"tidy3d/tasks/{self.task_id}")
293+
294+
task_details = http.get(f"tidy3d/tasks/{self.task_id}")
295+
296+
if task_details and "groupId" in task_details and "version" in task_details:
297+
group_id = task_details["groupId"]
298+
version = task_details["version"]
299+
if versions:
300+
http.delete("tidy3d/group", json={"groupIds": [group_id]})
301+
else:
302+
http.delete(f"tidy3d/group/{group_id}/versions", json={"versions": [version]})
303+
else: # Fallback to old method if we can't get the groupId and version
304+
http.delete(f"tidy3d/tasks/{self.task_id}")
288305

289306
def get_simulation_json(self, to_file: str, verbose: bool = True) -> pathlib.Path:
290307
"""Get json file for a :class:`.Simulation` from server.

0 commit comments

Comments
 (0)