Skip to content

Commit c0fae28

Browse files
committed
feat(restapi): add deleted boolean to resource responses
This feature adds a "deleted" boolean field to the response of all Resources. The field is set to true if the resources has been deleted and false otherwise. It updates the schema generators to include the new field, updates the response builders to populate the field in responses from the REST API, and update the tests to check for the existence and type of the field. Note that the REST API does not currently return deleted resources. A future change will enable this behavior.
1 parent ddcdb79 commit c0fae28

File tree

11 files changed

+39
-1
lines changed

11 files changed

+39
-1
lines changed

src/dioptra/restapi/v1/schemas.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ def generate_base_resource_schema(name: str, snapshot: bool) -> type[Schema]:
106106
many=True,
107107
dump_only=True,
108108
),
109+
"deleted": fields.Bool(
110+
attribute="deleted",
111+
metadata={"description": f"Whether the {name} resource has been deleted."},
112+
dump_only=True,
113+
load_default=False,
114+
),
109115
}
110116

111117
if not snapshot:
@@ -142,6 +148,12 @@ def generate_base_resource_ref_schema(
142148
metadata={"description": f"URL for accessing the full {name} resource."},
143149
relative=True,
144150
),
151+
"deleted": fields.Bool(
152+
attribute="deleted",
153+
metadata={"description": f"Whether the {name} resource has been deleted."},
154+
dump_only=True,
155+
load_default=False,
156+
),
145157
}
146158

147159
if keep_snapshot_id:

src/dioptra/restapi/v1/utils.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,7 @@ def build_experiment(experiment_dict: ExperimentDict) -> dict[str, Any]:
632632
"group": build_group_ref(experiment.resource.owner),
633633
"created_on": experiment.resource.created_on,
634634
"last_modified_on": experiment.resource.last_modified_on,
635+
"deleted": experiment.resource.is_deleted,
635636
"snapshot_created_on": experiment.created_on,
636637
"latest_snapshot": experiment.resource.latest_snapshot_id
637638
== experiment.resource_snapshot_id,
@@ -702,6 +703,7 @@ def build_entrypoint(entrypoint_dict: EntrypointDict) -> dict[str, Any]:
702703
"group": build_group_ref(entrypoint.resource.owner),
703704
"created_on": entrypoint.resource.created_on,
704705
"last_modified_on": entrypoint.resource.last_modified_on,
706+
"deleted": entrypoint.resource.is_deleted,
705707
"snapshot_created_on": entrypoint.created_on,
706708
"latest_snapshot": entrypoint.resource.latest_snapshot_id
707709
== entrypoint.resource_snapshot_id,
@@ -798,6 +800,7 @@ def build_job(job_dict: JobDict) -> dict[str, Any]:
798800
"created_on": job.resource.created_on,
799801
"last_modified_on": job.resource.last_modified_on,
800802
"snapshot_created_on": job.created_on,
803+
"deleted": job.resource.is_deleted,
801804
"latest_snapshot": job.resource.latest_snapshot_id == job.resource_snapshot_id,
802805
"tags": [build_tag_ref(tag) for tag in job.tags],
803806
}
@@ -852,6 +855,7 @@ def build_model(model_dict: ModelWithVersionDict) -> dict[str, Any]:
852855
"latest_snapshot": model.resource.latest_snapshot_id
853856
== model.resource_snapshot_id,
854857
"tags": [build_tag_ref(tag) for tag in model.tags],
858+
"deleted": model.resource.is_deleted,
855859
"latest_version": latest_version,
856860
"versions": versions,
857861
}
@@ -941,6 +945,7 @@ def build_artifact(artifact_dict: ArtifactDict) -> dict[str, Any]:
941945
"artifact_uri": artifact.uri,
942946
"is_dir": artifact.is_dir,
943947
"file_size": artifact.file_size,
948+
"deleted": artifact.resource.is_deleted,
944949
"task": build_artifact_artifact_task(artifact=artifact),
945950
"file_url": build_url(f"{ARTIFACTS}/{artifact.resource_id}/contents"),
946951
}
@@ -1005,6 +1010,7 @@ def build_queue(queue_dict: QueueDict) -> dict[str, Any]:
10051010
"group": build_group_ref(queue.resource.owner),
10061011
"created_on": queue.resource.created_on,
10071012
"last_modified_on": queue.resource.last_modified_on,
1013+
"deleted": queue.resource.is_deleted,
10081014
"snapshot_created_on": queue.created_on,
10091015
"latest_snapshot": queue.resource.latest_snapshot_id
10101016
== queue.resource_snapshot_id,
@@ -1039,6 +1045,7 @@ def build_plugin(plugin_with_files: PluginWithFilesDict) -> dict[str, Any]:
10391045
"group": build_group_ref(plugin.resource.owner),
10401046
"created_on": plugin.resource.created_on,
10411047
"last_modified_on": plugin.resource.last_modified_on,
1048+
"deleted": plugin.resource.is_deleted,
10421049
"snapshot_created_on": plugin.created_on,
10431050
"latest_snapshot": plugin.resource.latest_snapshot_id
10441051
== plugin.resource_snapshot_id,
@@ -1070,6 +1077,7 @@ def build_plugin_file(plugin_file_with_plugin: PluginFileDict) -> dict[str, Any]
10701077
"group": build_group_ref(plugin_file.resource.owner),
10711078
"created_on": plugin_file.resource.created_on,
10721079
"last_modified_on": plugin_file.resource.last_modified_on,
1080+
"deleted": plugin_file.resource.is_deleted,
10731081
"snapshot_created_on": plugin_file.created_on,
10741082
"latest_snapshot": plugin_file.resource.latest_snapshot_id
10751083
== plugin_file.resource_snapshot_id,
@@ -1201,6 +1209,7 @@ def build_plugin_parameter_type(
12011209
"group": build_group_ref(plugin_parameter_type.resource.owner),
12021210
"created_on": plugin_parameter_type.resource.created_on,
12031211
"last_modified_on": plugin_parameter_type.resource.last_modified_on,
1212+
"deleted": plugin_parameter_type.resource.is_deleted,
12041213
"snapshot_created_on": plugin_parameter_type.created_on,
12051214
"latest_snapshot": plugin_parameter_type.resource.latest_snapshot_id
12061215
== plugin_parameter_type.resource_snapshot_id,

tests/unit/restapi/lib/asserts.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def assert_base_resource_contents_match_expectations(response: dict[str, Any]) -
3535
assert isinstance(response["lastModifiedOn"], str)
3636
assert isinstance(response["latestSnapshot"], bool)
3737
assert isinstance(response["hasDraft"], bool)
38+
assert isinstance(response["deleted"], bool)
3839

3940
assert helpers.is_iso_format(response["createdOn"])
4041
assert helpers.is_iso_format(response["snapshotCreatedOn"])

tests/unit/restapi/v1/test_artifact.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ def assert_artifact_response_contents_matches_expectations(
6868
"fileUrl",
6969
"artifactUri",
7070
"job",
71+
"deleted",
7172
}
7273
assert set(response.keys()) == expected_keys
7374

@@ -85,6 +86,7 @@ def assert_artifact_response_contents_matches_expectations(
8586
assert isinstance(response["fileUrl"], str)
8687
assert isinstance(response["artifactUri"], str)
8788
assert isinstance(response["job"], int)
89+
assert isinstance(response["deleted"], bool)
8890

8991
assert response["artifactUri"] == expected_contents["artifactUri"]
9092
assert response["description"] == expected_contents["description"]

tests/unit/restapi/v1/test_entrypoint.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ def assert_entrypoint_response_contents_matches_expectations(
7070
"artifactPlugins",
7171
"queues",
7272
"tags",
73-
}
73+
"deleted",
74+
}
7475
assert set(response.keys()) == expected_keys
7576

7677
# Validate the non-Ref fields
@@ -83,6 +84,7 @@ def assert_entrypoint_response_contents_matches_expectations(
8384
assert isinstance(response["lastModifiedOn"], str)
8485
assert isinstance(response["latestSnapshot"], bool)
8586
assert isinstance(response["hasDraft"], bool)
87+
assert isinstance(response["deleted"], bool)
8688

8789
assert response["name"] == expected_contents["name"]
8890
assert response["description"] == expected_contents["description"]

tests/unit/restapi/v1/test_experiment.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def assert_experiment_response_contents_matches_expectations(
5555
"createdOn",
5656
"snapshotCreatedOn",
5757
"lastModifiedOn",
58+
"deleted",
5859
"latestSnapshot",
5960
"hasDraft",
6061
"name",
@@ -73,6 +74,7 @@ def assert_experiment_response_contents_matches_expectations(
7374
assert isinstance(response["snapshotCreatedOn"], str)
7475
assert isinstance(response["lastModifiedOn"], str)
7576
assert isinstance(response["latestSnapshot"], bool)
77+
assert isinstance(response["deleted"], bool)
7678

7779
assert response["name"] == expected_contents["name"]
7880
assert response["description"] == expected_contents["description"]

tests/unit/restapi/v1/test_job.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ def assert_job_response_contents_matches_expectations(
117117
"entrypoint",
118118
"artifacts",
119119
"artifactValues",
120+
"deleted",
120121
}
121122
assert set(response.keys()) == expected_keys
122123

tests/unit/restapi/v1/test_model.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ def assert_model_response_contents_matches_expectations(
6565
"description",
6666
"latestVersion",
6767
"tags",
68+
"deleted",
6869
}
6970
assert set(response.keys()) == expected_keys
7071

tests/unit/restapi/v1/test_plugin.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ def assert_plugin_response_contents_matches_expectations(
7070
"description",
7171
"files",
7272
"tags",
73+
"deleted",
7374
}
7475
assert set(response.keys()) == expected_keys
7576

@@ -83,6 +84,7 @@ def assert_plugin_response_contents_matches_expectations(
8384
assert isinstance(response["lastModifiedOn"], str)
8485
assert isinstance(response["latestSnapshot"], bool)
8586
assert isinstance(response["hasDraft"], bool)
87+
assert isinstance(response["deleted"], bool)
8688

8789
assert response["name"] == expected_contents["name"]
8890
assert response["description"] == expected_contents["description"]
@@ -284,6 +286,7 @@ def assert_plugin_file_response_contents_matches_expectations(
284286
"tasks",
285287
"tags",
286288
"plugin",
289+
"deleted",
287290
}
288291
assert set(response.keys()) == expected_keys
289292

@@ -298,6 +301,7 @@ def assert_plugin_file_response_contents_matches_expectations(
298301
assert isinstance(response["lastModifiedOn"], str)
299302
assert isinstance(response["latestSnapshot"], bool)
300303
assert isinstance(response["hasDraft"], bool)
304+
assert isinstance(response["deleted"], bool)
301305

302306
assert response["filename"] == expected_contents["filename"]
303307
assert response["description"] == expected_contents["description"]

tests/unit/restapi/v1/test_plugin_parameter_type.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ def assert_plugin_parameter_type_content_matches_expectations(
275275
"structure",
276276
"description",
277277
"tags",
278+
"deleted",
278279
}
279280
assert set(response.keys()) == expected_keys
280281

@@ -289,6 +290,7 @@ def assert_plugin_parameter_type_content_matches_expectations(
289290
assert isinstance(response["lastModifiedOn"], str)
290291
assert isinstance(response["latestSnapshot"], bool)
291292
assert isinstance(response["hasDraft"], bool)
293+
assert isinstance(response["deleted"], bool)
292294

293295
assert response["name"] == expected_contents["name"]
294296
assert response["structure"] == expected_contents["structure"]

0 commit comments

Comments
 (0)