Skip to content

Commit 3520ce4

Browse files
committed
Merge branch 'master' into 1973-refactor-create-start-inspect-methods
2 parents ce16bc4 + 8a62bd4 commit 3520ce4

File tree

33 files changed

+984
-18
lines changed

33 files changed

+984
-18
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)

packages/models-library/src/models_library/rpc/webserver/projects.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class ProjectJobRpcGet(BaseModel):
9090

9191
# Specific to jobs
9292
job_parent_resource_name: str
93+
storage_assets_deleted: bool
9394

9495
@staticmethod
9596
def _update_json_schema_extra(schema: JsonDict) -> None:
@@ -105,6 +106,7 @@ def _update_json_schema_extra(schema: JsonDict) -> None:
105106
"created_at": "2023-01-01T00:00:00Z",
106107
"modified_at": "2023-01-01T00:00:00Z",
107108
"job_parent_resource_name": "solvers/simcore%2Fservices%2Fcomp%2Fitis%2Fsleeper/releases/2.0.2",
109+
"storage_assets_deleted": "false",
108110
},
109111
{
110112
"uuid": "00000000-1234-5678-1234-123456789012",
@@ -114,6 +116,7 @@ def _update_json_schema_extra(schema: JsonDict) -> None:
114116
"created_at": "2023-02-01T00:00:00Z",
115117
"modified_at": "2023-02-01T00:00:00Z",
116118
"job_parent_resource_name": "studies/96642f2a-a72c-11ef-8776-02420a00087d",
119+
"storage_assets_deleted": "true",
117120
},
118121
{
119122
"uuid": "00000000-0000-5678-1234-123456789012",
@@ -123,6 +126,7 @@ def _update_json_schema_extra(schema: JsonDict) -> None:
123126
"created_at": "2023-03-01T00:00:00Z",
124127
"modified_at": "2023-03-01T00:00:00Z",
125128
"job_parent_resource_name": "program/simcore%2Fservices%2Fdynamic%2Fjupyter/releases/5.0.2",
129+
"storage_assets_deleted": "false",
126130
},
127131
]
128132
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""introduce data_deleted in projects_to_jobs table
2+
3+
Revision ID: 5b998370916a
4+
Revises: 5679165336c8
5+
Create Date: 2025-08-11 13:58:38.424398+00:00
6+
7+
"""
8+
9+
import sqlalchemy as sa
10+
from alembic import op
11+
12+
# revision identifiers, used by Alembic.
13+
revision = "5b998370916a"
14+
down_revision = "5679165336c8"
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
# ### commands auto generated by Alembic - please adjust! ###
21+
op.add_column(
22+
"projects_to_jobs",
23+
sa.Column("storage_assets_deleted", sa.Boolean(), nullable=True),
24+
)
25+
26+
op.execute("UPDATE projects_to_jobs SET storage_assets_deleted = false")
27+
28+
op.alter_column(
29+
"projects_to_jobs",
30+
"storage_assets_deleted",
31+
existing_type=sa.BOOLEAN(),
32+
nullable=False,
33+
)
34+
# ### end Alembic commands ###
35+
36+
37+
def downgrade():
38+
# ### commands auto generated by Alembic - please adjust! ###
39+
op.drop_column("projects_to_jobs", "storage_assets_deleted")
40+
# ### end Alembic commands ###

packages/postgres-database/src/simcore_postgres_database/models/projects_to_jobs.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@
2828
"the relative resource name is shelves/shelf1/jobs/job2, "
2929
"the parent resource name is shelves/shelf1.",
3030
),
31+
sa.Column(
32+
"storage_assets_deleted",
33+
sa.Boolean,
34+
nullable=False,
35+
doc="Indicates whether the job's S3 assets have been actively deleted.",
36+
),
3137
# Composite key (project_uuid, job_parent_resource_name) uniquely identifies very row
3238
sa.UniqueConstraint(
3339
"project_uuid",

packages/pytest-simcore/src/pytest_simcore/helpers/webserver_rpc_server.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@
2626
class WebserverRpcSideEffects:
2727
# pylint: disable=no-self-use
2828

29+
def __init__(
30+
self,
31+
project_job_rpc_get: ProjectJobRpcGet = ProjectJobRpcGet.model_validate(
32+
ProjectJobRpcGet.model_json_schema()["examples"][0]
33+
),
34+
):
35+
self.project_job_rpc_get = project_job_rpc_get
36+
2937
@validate_call(config={"arbitrary_types_allowed": True})
3038
async def mark_project_as_job(
3139
self,
@@ -35,12 +43,14 @@ async def mark_project_as_job(
3543
user_id: UserID,
3644
project_uuid: ProjectID,
3745
job_parent_resource_name: str,
46+
storage_assets_deleted: bool,
3847
) -> None:
3948
assert rpc_client
4049

4150
assert not job_parent_resource_name.startswith("/") # nosec
4251
assert "/" in job_parent_resource_name # nosec
4352
assert not job_parent_resource_name.endswith("/") # nosec
53+
assert isinstance(storage_assets_deleted, bool)
4454

4555
assert product_name
4656
assert user_id
@@ -84,3 +94,25 @@ async def list_projects_marked_as_jobs(
8494
limit=limit,
8595
offset=offset,
8696
)
97+
98+
@validate_call(config={"arbitrary_types_allowed": True})
99+
async def get_project_marked_as_job(
100+
self,
101+
rpc_client: RabbitMQRPCClient | MockType,
102+
*,
103+
product_name: ProductName,
104+
user_id: UserID,
105+
project_uuid: ProjectID,
106+
job_parent_resource_name: str,
107+
) -> ProjectJobRpcGet:
108+
assert rpc_client
109+
assert product_name
110+
assert user_id
111+
assert project_uuid
112+
assert job_parent_resource_name
113+
114+
# Return a valid example from the schema
115+
_data = self.project_job_rpc_get.model_dump()
116+
_data["uuid"] = str(project_uuid)
117+
_data["job_parent_resource_name"] = job_parent_resource_name
118+
return ProjectJobRpcGet.model_validate(_data)

packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/projects.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from models_library.rpc.webserver.projects import (
1010
ListProjectsMarkedAsJobRpcFilters,
1111
PageRpcProjectJobRpcGet,
12+
ProjectJobRpcGet,
1213
)
1314
from models_library.rpc_pagination import (
1415
DEFAULT_NUMBER_OF_ITEMS_PER_PAGE,
@@ -32,6 +33,7 @@ async def mark_project_as_job(
3233
user_id: UserID,
3334
project_uuid: ProjectID,
3435
job_parent_resource_name: str,
36+
storage_assets_deleted: bool,
3537
) -> None:
3638

3739
result = await rpc_client.request(
@@ -41,6 +43,7 @@ async def mark_project_as_job(
4143
user_id=user_id,
4244
project_uuid=project_uuid,
4345
job_parent_resource_name=job_parent_resource_name,
46+
storage_assets_deleted=storage_assets_deleted,
4447
)
4548
assert result is None
4649

@@ -68,3 +71,25 @@ async def list_projects_marked_as_jobs(
6871
)
6972
assert TypeAdapter(PageRpcProjectJobRpcGet).validate_python(result) # nosec
7073
return cast(PageRpcProjectJobRpcGet, result)
74+
75+
76+
@log_decorator(_logger, level=logging.DEBUG)
77+
@validate_call(config={"arbitrary_types_allowed": True})
78+
async def get_project_marked_as_job(
79+
rpc_client: RabbitMQRPCClient,
80+
*,
81+
product_name: ProductName,
82+
user_id: UserID,
83+
project_uuid: ProjectID,
84+
job_parent_resource_name: str,
85+
) -> ProjectJobRpcGet:
86+
result = await rpc_client.request(
87+
WEBSERVER_RPC_NAMESPACE,
88+
TypeAdapter(RPCMethodName).validate_python("get_project_marked_as_job"),
89+
product_name=product_name,
90+
user_id=user_id,
91+
project_uuid=project_uuid,
92+
job_parent_resource_name=job_parent_resource_name,
93+
)
94+
assert TypeAdapter(ProjectJobRpcGet).validate_python(result) # nosec
95+
return cast(ProjectJobRpcGet, result)

services/api-server/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.11.0
1+
0.12.0

services/api-server/openapi.json

Lines changed: 153 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"info": {
44
"title": "osparc.io public API",
55
"description": "osparc-simcore public API specifications",
6-
"version": "0.11.0"
6+
"version": "0.12.0"
77
},
88
"paths": {
99
"/v0/meta": {
@@ -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.12*",
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": [
@@ -2926,6 +3058,16 @@
29263058
}
29273059
}
29283060
},
3061+
"409": {
3062+
"description": "Job assets missing",
3063+
"content": {
3064+
"application/json": {
3065+
"schema": {
3066+
"$ref": "#/components/schemas/ErrorGet"
3067+
}
3068+
}
3069+
}
3070+
},
29293071
"422": {
29303072
"description": "Configuration error",
29313073
"content": {
@@ -3760,6 +3902,16 @@
37603902
}
37613903
}
37623904
},
3905+
"409": {
3906+
"description": "Job assets missing",
3907+
"content": {
3908+
"application/json": {
3909+
"schema": {
3910+
"$ref": "#/components/schemas/ErrorGet"
3911+
}
3912+
}
3913+
}
3914+
},
37633915
"422": {
37643916
"description": "Validation Error",
37653917
"content": {

services/api-server/setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.11.0
2+
current_version = 0.12.0
33
commit = True
44
message = services/api-server version: {current_version} → {new_version}
55
tag = False

0 commit comments

Comments
 (0)