diff --git a/antarest/study/model.py b/antarest/study/model.py index f8218fd31d..4307e99945 100644 --- a/antarest/study/model.py +++ b/antarest/study/model.py @@ -88,6 +88,12 @@ class Tag(Base): # type:ignore def __str__(self) -> str: return f"[Tag] label={self.label}, css-color-code={self.color}" + def __repr__(self) -> str: + cls = self.__class__.__name__ + label = getattr(self, "label", None) + color = getattr(self, "color", None) + return f"{cls}(label={label!r}, color={color!r})" + class StudyContentStatus(enum.Enum): VALID = "VALID" diff --git a/antarest/study/service.py b/antarest/study/service.py index 20d4640ffe..0a5cbe3875 100644 --- a/antarest/study/service.py +++ b/antarest/study/service.py @@ -527,7 +527,7 @@ def update_study_information( params.get_user_id(), ) study = self.get_study(uuid) - assert_permission(params.user, study, StudyPermissionType.READ) + assert_permission(params.user, study, StudyPermissionType.WRITE) if metadata_patch.horizon: study_settings_url = "settings/generaldata/general" @@ -550,9 +550,8 @@ def update_study_information( study.additional_data.author = metadata_patch.author if metadata_patch.horizon: study.additional_data.horizon = metadata_patch.horizon - - new_tags = metadata_patch.tags - self.repository.update_tags(study, new_tags) + if metadata_patch.tags: + self.repository.update_tags(study, metadata_patch.tags) new_metadata = self.storage_service.get_storage(study).patch_update_study_metadata(study, metadata_patch) diff --git a/antarest/study/storage/abstract_storage_service.py b/antarest/study/storage/abstract_storage_service.py index cd6b8be080..af76bf533d 100644 --- a/antarest/study/storage/abstract_storage_service.py +++ b/antarest/study/storage/abstract_storage_service.py @@ -1,3 +1,4 @@ +import json import logging import shutil import tempfile @@ -74,8 +75,10 @@ def get_study_information( additional_data = study.additional_data or StudyAdditionalData() try: - patch = Patch.parse_raw(additional_data.patch or "{}") - except Exception as e: + patch_obj = json.loads(additional_data.patch or "{}") + patch = Patch.parse_obj(patch_obj) + except ValueError as e: + # The conversion to JSON and the parsing can fail if the patch is not valid logger.warning(f"Failed to parse patch for study {study.id}", exc_info=e) patch = Patch() diff --git a/antarest/study/storage/patch_service.py b/antarest/study/storage/patch_service.py index c71833beb2..e3ece9071e 100644 --- a/antarest/study/storage/patch_service.py +++ b/antarest/study/storage/patch_service.py @@ -53,6 +53,6 @@ def save(self, study: Union[RawStudy, VariantStudy], patch: Patch) -> None: study.additional_data.patch = patch.json() self.repository.save(study) - patch_content = patch.json() patch_path = (Path(study.path)) / "patch.json" - patch_path.write_text(patch_content) + patch_path.parent.mkdir(parents=True, exist_ok=True) + patch_path.write_text(patch.json()) diff --git a/antarest/study/web/studies_blueprint.py b/antarest/study/web/studies_blueprint.py index f4b7a5e741..beeecd65c5 100644 --- a/antarest/study/web/studies_blueprint.py +++ b/antarest/study/web/studies_blueprint.py @@ -803,7 +803,7 @@ def archive_study( @bp.put( "/studies/{study_id}/unarchive", - summary="Dearchive a study", + summary="Unarchive a study", tags=[APITag.study_management], ) def unarchive_study( @@ -815,19 +815,6 @@ def unarchive_study( params = RequestParameters(user=current_user) return study_service.unarchive(study_id, params) - @bp.post( - "/studies/_invalidate_cache_listing", - summary="Invalidate the study listing cache [DEPRECATED] and will be removed soon", - tags=[APITag.study_management], - ) - def invalidate_study_listing_cache( - current_user: JWTUser = Depends(auth.get_current_user), - ) -> t.Any: - logger.info( - "Invalidating the study listing cache endpoint is deprecated", - extra={"user": current_user.id}, - ) - @bp.get( "/studies/{uuid}/disk-usage", summary="Compute study disk usage", diff --git a/tests/integration/studies_blueprint/test_get_studies.py b/tests/integration/studies_blueprint/test_get_studies.py index c9bf08bb62..869466e9f4 100644 --- a/tests/integration/studies_blueprint/test_get_studies.py +++ b/tests/integration/studies_blueprint/test_get_studies.py @@ -358,7 +358,9 @@ def test_study_listing( ) assert res.status_code in CREATE_STATUS_CODES, res.json() res = client.get( - STUDIES_URL, headers={"Authorization": f"Bearer {admin_access_token}"}, params={"name": "decennial-raw-850"} + STUDIES_URL, + headers={"Authorization": f"Bearer {admin_access_token}"}, + params={"name": "decennial-raw-850"}, ) assert res.status_code == LIST_STATUS_CODE, res.json() study_map: t.Dict[str, t.Dict[str, t.Any]] = res.json() @@ -373,14 +375,6 @@ def test_study_listing( ) assert res.status_code in CREATE_STATUS_CODES, res.json() tagged_variant_840_id = res.json() - res = client.put( - f"{STUDIES_URL}/{tagged_variant_840_id}/generate", - headers={"Authorization": f"Bearer {admin_access_token}"}, - ) - assert res.status_code == LIST_STATUS_CODE, res.json() - generation_task_id = res.json() - task = wait_task_completion(client, admin_access_token, generation_task_id) - assert task.status == TaskStatus.COMPLETED, task res = client.put( f"{STUDIES_URL}/{tagged_variant_840_id}", headers={"Authorization": f"Bearer {admin_access_token}"}, @@ -405,14 +399,6 @@ def test_study_listing( ) assert res.status_code in CREATE_STATUS_CODES, res.json() tagged_variant_850_id = res.json() - res = client.put( - f"{STUDIES_URL}/{tagged_variant_850_id}/generate", - headers={"Authorization": f"Bearer {admin_access_token}"}, - ) - assert res.status_code == LIST_STATUS_CODE, res.json() - generation_task_id = res.json() - task = wait_task_completion(client, admin_access_token, generation_task_id) - assert task.status == TaskStatus.COMPLETED, task res = client.put( f"{STUDIES_URL}/{tagged_variant_850_id}", headers={"Authorization": f"Bearer {admin_access_token}"}, diff --git a/tests/integration/test_integration.py b/tests/integration/test_integration.py index 03e3cbafe6..ffa4d4a91d 100644 --- a/tests/integration/test_integration.py +++ b/tests/integration/test_integration.py @@ -223,9 +223,6 @@ def test_main(client: TestClient, admin_access_token: str, study_id: str) -> Non assert len(res.json()) == 3 assert filter(lambda s: s["id"] == copied.json(), res.json().values()).__next__()["folder"] == "foo/bar" - res = client.post("/v1/studies/_invalidate_cache_listing", headers=admin_headers) - assert res.status_code == 200 - # Study delete client.delete( f"/v1/studies/{copied.json()}",