Skip to content

Commit 175ff33

Browse files
committed
Merge branch '219-delete-job-s3-data' into 219-webserver-part-for-deleting-job-data
2 parents 25364f7 + 1dece17 commit 175ff33

File tree

7 files changed

+190
-3
lines changed

7 files changed

+190
-3
lines changed

packages/models-library/src/models_library/api_schemas_webserver/projects.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ class ProjectPatch(InputSchema):
278278
] = None
279279
quality: dict[str, Any] | None = None
280280
template_type: ProjectTemplateType | None = None
281+
hidden: bool | None = None
281282

282283
def to_domain_model(self) -> dict[str, Any]:
283284
return self.model_dump(exclude_unset=True, by_alias=False)

services/api-server/openapi.json

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2761,6 +2761,138 @@
27612761
}
27622762
}
27632763
},
2764+
"/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}/assets": {
2765+
"delete": {
2766+
"tags": [
2767+
"solvers"
2768+
],
2769+
"summary": "Delete Job Assets",
2770+
"description": "Deletes assets associated with an existing solver job. N.B. this renders the solver job un-startable\n\nNew in *version 0.11*",
2771+
"operationId": "delete_job_assets",
2772+
"security": [
2773+
{
2774+
"HTTPBasic": []
2775+
}
2776+
],
2777+
"parameters": [
2778+
{
2779+
"name": "solver_key",
2780+
"in": "path",
2781+
"required": true,
2782+
"schema": {
2783+
"type": "string",
2784+
"pattern": "^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$",
2785+
"title": "Solver Key"
2786+
}
2787+
},
2788+
{
2789+
"name": "version",
2790+
"in": "path",
2791+
"required": true,
2792+
"schema": {
2793+
"type": "string",
2794+
"pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$",
2795+
"title": "Version"
2796+
}
2797+
},
2798+
{
2799+
"name": "job_id",
2800+
"in": "path",
2801+
"required": true,
2802+
"schema": {
2803+
"type": "string",
2804+
"format": "uuid",
2805+
"title": "Job Id"
2806+
}
2807+
}
2808+
],
2809+
"responses": {
2810+
"204": {
2811+
"description": "Successful Response"
2812+
},
2813+
"402": {
2814+
"description": "Payment required",
2815+
"content": {
2816+
"application/json": {
2817+
"schema": {
2818+
"$ref": "#/components/schemas/ErrorGet"
2819+
}
2820+
}
2821+
}
2822+
},
2823+
"404": {
2824+
"description": "Job/wallet/pricing details not found",
2825+
"content": {
2826+
"application/json": {
2827+
"schema": {
2828+
"$ref": "#/components/schemas/ErrorGet"
2829+
}
2830+
}
2831+
}
2832+
},
2833+
"429": {
2834+
"description": "Too many requests",
2835+
"content": {
2836+
"application/json": {
2837+
"schema": {
2838+
"$ref": "#/components/schemas/ErrorGet"
2839+
}
2840+
}
2841+
}
2842+
},
2843+
"500": {
2844+
"description": "Internal server error",
2845+
"content": {
2846+
"application/json": {
2847+
"schema": {
2848+
"$ref": "#/components/schemas/ErrorGet"
2849+
}
2850+
}
2851+
}
2852+
},
2853+
"502": {
2854+
"description": "Unexpected error when communicating with backend service",
2855+
"content": {
2856+
"application/json": {
2857+
"schema": {
2858+
"$ref": "#/components/schemas/ErrorGet"
2859+
}
2860+
}
2861+
}
2862+
},
2863+
"503": {
2864+
"description": "Service unavailable",
2865+
"content": {
2866+
"application/json": {
2867+
"schema": {
2868+
"$ref": "#/components/schemas/ErrorGet"
2869+
}
2870+
}
2871+
}
2872+
},
2873+
"504": {
2874+
"description": "Request to a backend service timed out.",
2875+
"content": {
2876+
"application/json": {
2877+
"schema": {
2878+
"$ref": "#/components/schemas/ErrorGet"
2879+
}
2880+
}
2881+
}
2882+
},
2883+
"422": {
2884+
"description": "Validation Error",
2885+
"content": {
2886+
"application/json": {
2887+
"schema": {
2888+
"$ref": "#/components/schemas/HTTPValidationError"
2889+
}
2890+
}
2891+
}
2892+
}
2893+
}
2894+
}
2895+
},
27642896
"/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}:start": {
27652897
"post": {
27662898
"tags": [

services/api-server/src/simcore_service_api_server/_service_jobs.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55

66
from common_library.exclude import as_dict_exclude_none
77
from models_library.api_schemas_rpc_async_jobs.async_jobs import AsyncJobGet
8-
from models_library.api_schemas_webserver.projects import ProjectCreateNew, ProjectGet
8+
from models_library.api_schemas_webserver.projects import (
9+
ProjectCreateNew,
10+
ProjectGet,
11+
ProjectPatch,
12+
)
913
from models_library.products import ProductName
1014
from models_library.projects import ProjectID
1115
from models_library.projects_nodes_io import NodeID
@@ -27,6 +31,7 @@
2731
create_job_inputs_from_node_inputs,
2832
create_new_project_for_job,
2933
)
34+
from .services_http.storage import StorageApi
3035
from .services_http.webserver import AuthSession
3136
from .services_rpc.director_v2 import DirectorV2Service
3237
from .services_rpc.storage import StorageService
@@ -40,6 +45,7 @@ class JobService:
4045
_web_rest_client: AuthSession
4146
_web_rpc_client: WbApiRpcClient
4247
_storage_rpc_client: StorageService
48+
_storage_rest_client: StorageApi
4349
_directorv2_rpc_client: DirectorV2Service
4450
user_id: UserID
4551
product_name: ProductName
@@ -168,3 +174,12 @@ async def start_log_export(
168174
],
169175
)
170176
return async_job_get
177+
178+
async def delete_project_assets(self, project_id: ProjectID):
179+
"""Marks job project as hidden and deletes S3 assets associated it"""
180+
await self._web_rest_client.patch_project(
181+
project_id=project_id, patch_params=ProjectPatch(hidden=True)
182+
)
183+
await self._storage_rest_client.delete_project_s3_assets(
184+
user_id=self.user_id, project_id=project_id
185+
)

services/api-server/src/simcore_service_api_server/api/dependencies/services.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from ..._service_programs import ProgramService
1313
from ..._service_solvers import SolverService
1414
from ..._service_studies import StudyService
15+
from ...services_http.storage import StorageApi
1516
from ...services_http.webserver import AuthSession
1617
from ...services_rpc.catalog import CatalogService
1718
from ...services_rpc.director_v2 import DirectorV2Service
@@ -84,7 +85,8 @@ def get_directorv2_service(
8485
def get_job_service(
8586
web_rest_api: Annotated[AuthSession, Depends(get_webserver_session)],
8687
web_rpc_api: Annotated[WbApiRpcClient, Depends(get_wb_api_rpc_client)],
87-
storage_service: Annotated[StorageService, Depends(get_storage_service)],
88+
storage_rpc_client: Annotated[StorageService, Depends(get_storage_service)],
89+
storage_rest_client: Annotated[StorageApi, Depends(get_api_client(StorageApi))],
8890
directorv2_service: Annotated[DirectorV2Service, Depends(get_directorv2_service)],
8991
user_id: Annotated[UserID, Depends(get_current_user_id)],
9092
product_name: Annotated[ProductName, Depends(get_product_name)],
@@ -96,7 +98,8 @@ def get_job_service(
9698
return JobService(
9799
_web_rest_client=web_rest_api,
98100
_web_rpc_client=web_rpc_api,
99-
_storage_rpc_client=storage_service,
101+
_storage_rpc_client=storage_rpc_client,
102+
_storage_rest_client=storage_rest_client,
100103
_directorv2_rpc_client=directorv2_service,
101104
user_id=user_id,
102105
product_name=product_name,

services/api-server/src/simcore_service_api_server/api/routes/solvers_jobs.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,26 @@ async def delete_job(
151151
await webserver_api.delete_project(project_id=job_id)
152152

153153

154+
@router.delete(
155+
"/{solver_key:path}/releases/{version}/jobs/{job_id:uuid}/assets",
156+
status_code=status.HTTP_204_NO_CONTENT,
157+
responses=JOBS_STATUS_CODES,
158+
description=create_route_description(
159+
base="Deletes assets associated with an existing solver job. N.B. this renders the solver job un-startable",
160+
changelog=[
161+
FMSG_CHANGELOG_NEW_IN_VERSION.format("0.11"),
162+
],
163+
),
164+
)
165+
async def delete_job_assets(
166+
solver_key: SolverKeyId,
167+
version: VersionStr,
168+
job_id: JobID,
169+
job_service: Annotated[JobService, Depends(get_job_service)],
170+
):
171+
await job_service.delete_project_assets(project_id=job_id)
172+
173+
154174
@router.post(
155175
"/{solver_key:path}/releases/{version}/jobs/{job_id:uuid}:start",
156176
status_code=status.HTTP_202_ACCEPTED,

services/api-server/src/simcore_service_api_server/services_http/storage.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
)
3030
from models_library.basic_types import SHA256Str
3131
from models_library.generics import Envelope
32+
from models_library.projects import ProjectID
3233
from models_library.rest_pagination import PageLimitInt, PageOffsetInt
3334
from pydantic import AnyUrl
3435
from settings_library.tracing import TracingSettings
@@ -284,6 +285,16 @@ async def create_soft_link(
284285
file_meta: File = to_file_api_model(stored_file_meta)
285286
return file_meta
286287

288+
@_exception_mapper(http_status_map={})
289+
async def delete_project_s3_assets(
290+
self, user_id: int, project_id: ProjectID
291+
) -> None:
292+
response = await self.client.delete(
293+
f"/locations/{self.SIMCORE_S3_ID}/folders/{project_id}",
294+
params={"user_id": user_id},
295+
)
296+
response.raise_for_status()
297+
287298

288299
# MODULES APP SETUP -------------------------------------------------------------
289300

services/web/server/src/simcore_service_webserver/api/v0/openapi.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15702,6 +15702,11 @@ components:
1570215702
anyOf:
1570315703
- $ref: '#/components/schemas/ProjectTemplateType'
1570415704
- type: 'null'
15705+
hidden:
15706+
anyOf:
15707+
- type: boolean
15708+
- type: 'null'
15709+
title: Hidden
1570515710
type: object
1570615711
title: ProjectPatch
1570715712
ProjectPermalink:

0 commit comments

Comments
 (0)