Skip to content

Commit b3c78e9

Browse files
committed
propagate name and description when creating program jobs
1 parent d0f485b commit b3c78e9

File tree

6 files changed

+97
-21
lines changed

6 files changed

+97
-21
lines changed

services/api-server/openapi.json

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1321,7 +1321,7 @@
13211321
"programs"
13221322
],
13231323
"summary": "Create Program Job",
1324-
"description": "Creates a job in a specific release with given inputs.\n\nNOTE: This operation does **not** start the job",
1324+
"description": "Creates a program job",
13251325
"operationId": "create_program_job",
13261326
"security": [
13271327
{
@@ -1384,6 +1384,15 @@
13841384
}
13851385
}
13861386
],
1387+
"requestBody": {
1388+
"content": {
1389+
"application/json": {
1390+
"schema": {
1391+
"$ref": "#/components/schemas/Body_create_program_job_v0_programs__program_key__releases__version__jobs_post"
1392+
}
1393+
}
1394+
}
1395+
},
13871396
"responses": {
13881397
"201": {
13891398
"description": "Successful Response",
@@ -6056,6 +6065,34 @@
60566065
],
60576066
"title": "Body_complete_multipart_upload_v0_files__file_id__complete_post"
60586067
},
6068+
"Body_create_program_job_v0_programs__program_key__releases__version__jobs_post": {
6069+
"properties": {
6070+
"name": {
6071+
"anyOf": [
6072+
{
6073+
"type": "string"
6074+
},
6075+
{
6076+
"type": "null"
6077+
}
6078+
],
6079+
"title": "Name"
6080+
},
6081+
"description": {
6082+
"anyOf": [
6083+
{
6084+
"type": "string"
6085+
},
6086+
{
6087+
"type": "null"
6088+
}
6089+
],
6090+
"title": "Description"
6091+
}
6092+
},
6093+
"type": "object",
6094+
"title": "Body_create_program_job_v0_programs__program_key__releases__version__jobs_post"
6095+
},
60596096
"Body_upload_file_v0_files_content_put": {
60606097
"properties": {
60616098
"file": {

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

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,21 @@
44

55
from fastapi import Depends
66
from models_library.api_schemas_webserver.projects import ProjectCreateNew, ProjectGet
7+
from models_library.products import ProductName
78
from models_library.projects import ProjectID
89
from models_library.projects_nodes_io import NodeID
10+
from models_library.users import UserID
911
from pydantic import HttpUrl
1012
from servicelib.fastapi.app_state import SingletonInAppStateMixin
1113
from servicelib.logging_utils import log_context
14+
from simcore_service_api_server.api.dependencies.authentication import (
15+
get_current_user_id,
16+
get_product_name,
17+
)
18+
from simcore_service_api_server.api.dependencies.webserver_rpc import (
19+
get_wb_api_rpc_client,
20+
)
21+
from simcore_service_api_server.services_rpc.wb_api_server import WbApiRpcClient
1222

1323
from .api.dependencies.webserver_http import get_webserver_session
1424
from .models.schemas.jobs import Job, JobInputs
@@ -26,11 +36,22 @@
2636
class JobService(SingletonInAppStateMixin):
2737
app_state_name = "JobService"
2838
_web_rest_api: AuthSession
39+
_web_rpc_api: WbApiRpcClient
40+
_user_id: UserID
41+
_product_name: ProductName
2942

3043
def __init__(
31-
self, web_rest_api: Annotated[AuthSession, Depends(get_webserver_session)]
44+
self,
45+
*,
46+
web_rest_api: Annotated[AuthSession, Depends(get_webserver_session)],
47+
web_rpc_api: Annotated[WbApiRpcClient, Depends(get_wb_api_rpc_client)],
48+
user_id: Annotated[UserID, Depends(get_current_user_id)],
49+
product_name: Annotated[ProductName, Depends(get_product_name)],
3250
):
3351
self._web_rest_api = web_rest_api
52+
self._web_rpc_api = web_rpc_api
53+
self._user_id = user_id
54+
self._product_name = product_name
3455

3556
async def create_job(
3657
self,
@@ -41,23 +62,34 @@ async def create_job(
4162
parent_node_id: NodeID | None,
4263
url_for: Callable[..., HttpUrl],
4364
hidden: bool,
65+
name: str | None,
66+
description: str | None,
4467
) -> tuple[Job, ProjectGet]:
4568
# creates NEW job as prototype
4669
pre_job = Job.create_job_from_solver_or_program(
47-
solver_or_program_name=solver_or_program.name, inputs=inputs
70+
solver_or_program_name=solver_or_program.name, inputs=inputs, name=name
4871
)
4972
with log_context(
5073
logger=_logger, level=logging.DEBUG, msg=f"Creating job {pre_job.name}"
5174
):
5275
project_in: ProjectCreateNew = create_new_project_for_job(
53-
solver_or_program, pre_job, inputs
76+
solver_or_program=solver_or_program,
77+
job=pre_job,
78+
inputs=inputs,
79+
description=description,
5480
)
5581
new_project: ProjectGet = await self._web_rest_api.create_project(
5682
project_in,
5783
is_hidden=hidden,
5884
parent_project_uuid=parent_project_uuid,
5985
parent_node_id=parent_node_id,
6086
)
87+
await self._web_rpc_api.mark_project_as_job(
88+
product_name=self._product_name,
89+
user_id=self._user_id,
90+
project_uuid=new_project.uuid,
91+
job_parent_resource_name=pre_job.runner_name,
92+
)
6193

6294
assert new_project # nosec
6395
assert new_project.uuid == pre_job.id # nosec

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from collections.abc import Callable
33
from typing import Annotated
44

5-
from fastapi import APIRouter, Depends, Header, HTTPException, status
5+
from fastapi import APIRouter, Body, Depends, Header, HTTPException, status
66
from httpx import HTTPStatusError
77
from models_library.api_schemas_storage.storage_schemas import (
88
LinkType,
@@ -81,11 +81,10 @@ async def create_program_job(
8181
product_name: Annotated[str, Depends(get_product_name)],
8282
x_simcore_parent_project_uuid: Annotated[ProjectID | None, Header()] = None,
8383
x_simcore_parent_node_id: Annotated[NodeID | None, Header()] = None,
84+
name: Annotated[str | None, Body()] = None,
85+
description: Annotated[str | None, Body()] = None,
8486
):
85-
"""Creates a job in a specific release with given inputs.
86-
87-
NOTE: This operation does **not** start the job
88-
"""
87+
"""Creates a program job"""
8988

9089
# ensures user has access to solver
9190
inputs = JobInputs(values={})
@@ -97,13 +96,16 @@ async def create_program_job(
9796
)
9897

9998
job, project = await job_service.create_job(
99+
name=name,
100+
description=description,
100101
solver_or_program=program,
101102
inputs=inputs,
102103
parent_project_uuid=x_simcore_parent_project_uuid,
103104
parent_node_id=x_simcore_parent_node_id,
104105
url_for=url_for,
105106
hidden=False,
106107
)
108+
107109
# create workspace directory so files can be uploaded to it
108110
assert len(project.workbench) > 0 # nosec
109111
node_id = next(iter(project.workbench))

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@ async def create_solver_job(
116116
version=version,
117117
product_name=product_name,
118118
)
119-
job, project = await job_service.create_job(
119+
job, _ = await job_service.create_job(
120+
name=None,
121+
description=None,
120122
solver_or_program=solver,
121123
inputs=inputs,
122124
url_for=url_for,
@@ -125,12 +127,6 @@ async def create_solver_job(
125127
parent_node_id=x_simcore_parent_node_id,
126128
)
127129

128-
await wb_api_rpc.mark_project_as_job(
129-
product_name=product_name,
130-
user_id=user_id,
131-
project_uuid=project.uuid,
132-
job_parent_resource_name=job.runner_name,
133-
)
134130
return job
135131

136132

services/api-server/src/simcore_service_api_server/models/schemas/jobs.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -288,12 +288,15 @@ def _check_name(cls, v, info: ValidationInfo):
288288

289289
@classmethod
290290
def create_now(
291-
cls, parent_name: RelativeResourceName, inputs_checksum: str
291+
cls,
292+
parent_name: RelativeResourceName,
293+
inputs_checksum: str,
294+
name: str | None = None,
292295
) -> "Job":
293296
global_uuid = uuid4()
294297

295298
return cls(
296-
name=cls.compose_resource_name(parent_name, global_uuid),
299+
name=name or cls.compose_resource_name(parent_name, global_uuid),
297300
id=global_uuid,
298301
runner_name=parent_name,
299302
inputs_checksum=inputs_checksum,
@@ -305,9 +308,10 @@ def create_now(
305308

306309
@classmethod
307310
def create_job_from_solver_or_program(
308-
cls, *, solver_or_program_name: str, inputs: JobInputs
311+
cls, *, solver_or_program_name: str, inputs: JobInputs, name: str | None = None
309312
):
310313
return Job.create_now(
314+
name=name,
311315
parent_name=solver_or_program_name,
312316
inputs_checksum=inputs.compute_checksum(),
313317
)

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,11 @@ def get_node_id(project_id, solver_id) -> str:
119119

120120

121121
def create_new_project_for_job(
122-
solver_or_program: Solver | Program, job: Job, inputs: JobInputs
122+
*,
123+
solver_or_program: Solver | Program,
124+
job: Job,
125+
inputs: JobInputs,
126+
description: str | None = None,
123127
) -> ProjectCreateNew:
124128
"""
125129
Creates a project for a solver's job
@@ -159,7 +163,8 @@ def create_new_project_for_job(
159163
return ProjectCreateNew(
160164
uuid=project_id,
161165
name=job.name, # NOTE: this IS an identifier as well. MUST NOT be changed in the case of project APIs!
162-
description=f"Study associated to solver job:\n{job_info}",
166+
description=description
167+
or f"Study associated to solver/study/program job:\n{job_info}",
163168
thumbnail="https://via.placeholder.com/170x120.png", # type: ignore[arg-type]
164169
workbench={solver_id: solver_service},
165170
ui=StudyUI(

0 commit comments

Comments
 (0)