Skip to content

Commit 1d86dc3

Browse files
committed
cleanup
1 parent 3378148 commit 1d86dc3

File tree

4 files changed

+43
-39
lines changed

4 files changed

+43
-39
lines changed

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

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,11 @@
2222
from models_library.users import UserID
2323
from pydantic import HttpUrl
2424
from servicelib.logging_utils import log_context
25-
from simcore_service_api_server.api.routes.solvers_jobs import compose_job_resource_name
2625

2726
from ._service_solvers import (
2827
SolverService,
2928
)
30-
from .exceptions.backend_errors import JobAssetsMissingError, ProjectAlreadyStartedError
29+
from .exceptions.backend_errors import JobAssetsMissingError
3130
from .exceptions.custom_errors import SolverServiceListJobsFiltersError
3231
from .models.api_resources import RelativeResourceName
3332
from .models.basic_types import NameValueTuple, VersionStr
@@ -59,6 +58,14 @@
5958
_logger = logging.getLogger(__name__)
6059

6160

61+
def compose_job_resource_name(solver_key, solver_version, job_id) -> str:
62+
"""Creates a unique resource name for solver's jobs"""
63+
return Job.compose_resource_name(
64+
parent_name=Solver.compose_resource_name(solver_key, solver_version),
65+
job_id=job_id,
66+
)
67+
68+
6269
@dataclass(frozen=True, kw_only=True)
6370
class JobService:
6471
_web_rest_client: AuthSession
@@ -335,6 +342,9 @@ async def start_solver_job(
335342
job_id: JobID,
336343
pricing_spec: JobPricingSpecification | None,
337344
):
345+
"""
346+
Raises ProjectAlreadyStartedError if the project is already started
347+
"""
338348
job_name = compose_job_resource_name(solver_key, version, job_id)
339349
_logger.debug("Start Job '%s'", job_name)
340350
job_parent_resource_name = Solver.compose_resource_name(solver_key, version)
@@ -343,20 +353,12 @@ async def start_solver_job(
343353
)
344354
if job.storage_assets_deleted:
345355
raise JobAssetsMissingError(job_id=job_id)
346-
try:
347-
await start_project(
348-
pricing_spec=pricing_spec,
349-
job_id=job_id,
350-
expected_job_name=job_name,
351-
webserver_api=self._web_rest_client,
352-
)
353-
except ProjectAlreadyStartedError:
354-
job_status = await self.inspect_solver_job(
355-
solver_key=solver_key,
356-
version=version,
357-
job_id=job_id,
358-
)
359-
return job_status
356+
await start_project(
357+
pricing_spec=pricing_spec,
358+
job_id=job_id,
359+
expected_job_name=job_name,
360+
webserver_api=self._web_rest_client,
361+
)
360362
return await self.inspect_solver_job(
361363
solver_key=solver_key,
362364
version=version,

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

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
from typing import Annotated, Any
66

77
from fastapi import APIRouter, Depends, Header, Query, Request, status
8+
from fastapi.responses import JSONResponse
89
from models_library.clusters import ClusterID
910
from models_library.projects import ProjectID
1011
from models_library.projects_nodes_io import NodeID
1112
from pydantic.types import PositiveInt
1213

13-
from ..._service_jobs import JobService
14+
from ..._service_jobs import JobService, compose_job_resource_name
15+
from ...exceptions.backend_errors import ProjectAlreadyStartedError
1416
from ...exceptions.service_errors_utils import DEFAULT_BACKEND_SERVICE_STATUS_CODES
1517
from ...models.basic_types import VersionStr
1618
from ...models.schemas.errors import ErrorGet
@@ -42,14 +44,6 @@
4244
router = APIRouter()
4345

4446

45-
def compose_job_resource_name(solver_key, solver_version, job_id) -> str:
46-
"""Creates a unique resource name for solver's jobs"""
47-
return Job.compose_resource_name(
48-
parent_name=Solver.compose_resource_name(solver_key, solver_version),
49-
job_id=job_id,
50-
)
51-
52-
5347
# JOBS ---------------
5448
#
5549
# - Similar to docker container's API design (container = job and image = solver)
@@ -216,9 +210,20 @@ async def start_job(
216210
):
217211
pricing_spec = JobPricingSpecification.create_from_headers(headers=request.headers)
218212

219-
return await job_service.start_solver_job(
220-
solver_key=solver_key, version=version, job_id=job_id, pricing_spec=pricing_spec
221-
)
213+
try:
214+
return await job_service.start_solver_job(
215+
solver_key=solver_key,
216+
version=version,
217+
job_id=job_id,
218+
pricing_spec=pricing_spec,
219+
)
220+
except ProjectAlreadyStartedError:
221+
job_status = await job_service.inspect_solver_job(
222+
solver_key=solver_key, version=version, job_id=job_id
223+
)
224+
return JSONResponse(
225+
status_code=status.HTTP_200_OK, content=job_status.model_dump(mode="json")
226+
)
222227

223228

224229
@router.post(

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
JobMetadata,
2929
JobMetadataUpdate,
3030
JobOutputs,
31+
JobPricingSpecification,
3132
JobStatus,
3233
)
3334
from ...models.schemas.studies import JobLogsMap, Study, StudyID
@@ -288,14 +289,16 @@ async def start_study_job(
288289
),
289290
] = None,
290291
):
292+
pricing_spec = JobPricingSpecification.create_from_headers(headers=request.headers)
293+
291294
job_name = _compose_job_resource_name(study_id, job_id)
292295
with log_context(_logger, logging.DEBUG, f"Starting Job '{job_name}'"):
293296
try:
294297
await start_project(
295-
request=request,
296298
job_id=job_id,
297299
expected_job_name=job_name,
298300
webserver_api=webserver_api,
301+
pricing_spec=pricing_spec,
299302
)
300303
except ProjectAlreadyStartedError:
301304
job_status: JobStatus = await inspect_study_job(

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

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
import logging
2-
from typing import Annotated
32
from uuid import UUID
43

5-
from fastapi import Depends, HTTPException, status
64
from models_library.api_schemas_webserver.projects import ProjectGet
75
from pydantic import HttpUrl, PositiveInt
86
from servicelib.logging_utils import log_context
97

10-
from ..api.dependencies.authentication import get_current_user_id
11-
from ..api.dependencies.services import get_api_client
8+
from ..exceptions.backend_errors import InvalidInputError
129
from ..models.schemas.jobs import (
1310
JobID,
1411
JobMetadata,
@@ -27,10 +24,7 @@ def raise_if_job_not_associated_with_solver(
2724
expected_project_name: str, project: ProjectGet
2825
) -> None:
2926
if expected_project_name != project.name:
30-
raise HTTPException(
31-
status.HTTP_422_UNPROCESSABLE_ENTITY,
32-
detail=f"Invalid input data for job {project.uuid}",
33-
)
27+
raise InvalidInputError()
3428

3529

3630
async def start_project(
@@ -59,8 +53,8 @@ async def start_project(
5953
async def stop_project(
6054
*,
6155
job_id: JobID,
62-
user_id: Annotated[PositiveInt, Depends(get_current_user_id)],
63-
director2_api: Annotated[DirectorV2Api, Depends(get_api_client(DirectorV2Api))],
56+
user_id: PositiveInt,
57+
director2_api: DirectorV2Api,
6458
) -> JobStatus:
6559
await director2_api.stop_computation(project_id=job_id, user_id=user_id)
6660

0 commit comments

Comments
 (0)