Skip to content

Commit 30d0977

Browse files
committed
ensure only pydantic models are passed from function run and map endpoints
1 parent a137e8d commit 30d0977

File tree

3 files changed

+44
-23
lines changed

3 files changed

+44
-23
lines changed

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

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from collections.abc import Callable
21
from dataclasses import dataclass
32

43
import jsonschema
@@ -36,16 +35,11 @@
3635
from pydantic import ValidationError
3736

3837
from ._service_jobs import JobService
38+
from .models.api_resources import JobLinks
3939
from .models.schemas.jobs import (
4040
JobInputs,
4141
JobPricingSpecification,
4242
)
43-
from .services_http.solver_job_models_converters import (
44-
get_solver_job_rest_interface_links,
45-
)
46-
from .services_http.study_job_models_converters import (
47-
get_study_job_rest_interface_links,
48-
)
4943
from .services_rpc.wb_api_server import WbApiRpcClient
5044

5145

@@ -172,7 +166,7 @@ async def run_function(
172166
function: RegisteredFunction,
173167
function_inputs: FunctionInputs,
174168
pricing_spec: JobPricingSpecification | None,
175-
url_for: Callable,
169+
job_links: JobLinks,
176170
x_simcore_parent_project_uuid: NodeID | None,
177171
x_simcore_parent_node_id: NodeID | None,
178172
) -> RegisteredFunctionJob:
@@ -227,9 +221,6 @@ async def run_function(
227221
return cached_function_job
228222

229223
if function.function_class == FunctionClass.PROJECT:
230-
job_links = get_study_job_rest_interface_links(
231-
url_for=url_for, study_id=function.project_id
232-
)
233224
study_job = await self._job_service.create_studies_job(
234225
study_id=function.project_id,
235226
job_inputs=JobInputs(values=joined_inputs or {}),
@@ -257,16 +248,11 @@ async def run_function(
257248
)
258249

259250
if function.function_class == FunctionClass.SOLVER:
260-
job_rest_interface_links = get_solver_job_rest_interface_links(
261-
url_for=url_for,
262-
solver_key=function.solver_key,
263-
version=function.solver_version,
264-
)
265251
solver_job = await self._job_service.create_solver_job(
266252
solver_key=function.solver_key,
267253
version=function.solver_version,
268254
inputs=JobInputs(values=joined_inputs or {}),
269-
job_links=job_rest_interface_links,
255+
job_links=job_links,
270256
hidden=True,
271257
x_simcore_parent_project_uuid=x_simcore_parent_project_uuid,
272258
x_simcore_parent_node_id=x_simcore_parent_node_id,
@@ -299,8 +285,8 @@ async def map_function(
299285
*,
300286
function: RegisteredFunction,
301287
function_inputs_list: FunctionInputsList,
288+
job_links: JobLinks,
302289
pricing_spec: JobPricingSpecification | None,
303-
url_for: Callable,
304290
x_simcore_parent_project_uuid: ProjectID | None,
305291
x_simcore_parent_node_id: NodeID | None,
306292
) -> RegisteredFunctionJobCollection:
@@ -310,7 +296,7 @@ async def map_function(
310296
function=function,
311297
function_inputs=function_inputs,
312298
pricing_spec=pricing_spec,
313-
url_for=url_for,
299+
job_links=job_links,
314300
x_simcore_parent_project_uuid=x_simcore_parent_project_uuid,
315301
x_simcore_parent_node_id=x_simcore_parent_node_id,
316302
)

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

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
from collections.abc import Callable
12
from dataclasses import dataclass
23

34
from common_library.exclude import as_dict_exclude_none
4-
from models_library.functions import RegisteredFunction
5+
from models_library.functions import FunctionClass, RegisteredFunction
6+
from models_library.functions_errors import UnsupportedFunctionClassError
57
from models_library.products import ProductName
68
from models_library.rest_pagination import (
79
MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE,
@@ -10,7 +12,15 @@
1012
)
1113
from models_library.rpc_pagination import PageLimitInt
1214
from models_library.users import UserID
13-
from simcore_service_api_server.services_rpc.wb_api_server import WbApiRpcClient
15+
16+
from .models.api_resources import JobLinks
17+
from .services_http.solver_job_models_converters import (
18+
get_solver_job_rest_interface_links,
19+
)
20+
from .services_http.study_job_models_converters import (
21+
get_study_job_rest_interface_links,
22+
)
23+
from .services_rpc.wb_api_server import WbApiRpcClient
1424

1525
DEFAULT_PAGINATION_LIMIT = MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE - 1
1626

@@ -38,3 +48,22 @@ async def list_functions(
3848
product_name=self.product_name,
3949
**pagination_kwargs,
4050
)
51+
52+
async def get_function_job_links(
53+
self, function: RegisteredFunction, url_for: Callable
54+
) -> JobLinks:
55+
if function.function_class == FunctionClass.SOLVER:
56+
return get_solver_job_rest_interface_links(
57+
url_for=url_for,
58+
solver_key=function.solver_key,
59+
version=function.solver_version,
60+
)
61+
elif function.function_class == FunctionClass.PROJECT:
62+
return get_study_job_rest_interface_links(
63+
url_for=url_for,
64+
study_id=function.project_id,
65+
)
66+
else:
67+
raise UnsupportedFunctionClassError(
68+
function_class=function.function_class,
69+
)

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ async def run_function( # noqa: PLR0913
316316
to_run_function: Annotated[RegisteredFunction, Depends(get_function)],
317317
url_for: Annotated[Callable, Depends(get_reverse_url_mapper)],
318318
function_inputs: FunctionInputs,
319+
function_service: Annotated[FunctionService, Depends(get_function_service)],
319320
function_jobs_service: Annotated[
320321
FunctionJobService, Depends(get_function_job_service)
321322
],
@@ -333,11 +334,13 @@ async def run_function( # noqa: PLR0913
333334
else None
334335
)
335336
pricing_spec = JobPricingSpecification.create_from_headers(request.headers)
337+
job_links = await function_service.get_function_job_links(to_run_function, url_for)
338+
336339
return await function_jobs_service.run_function(
337340
function=to_run_function,
338341
function_inputs=function_inputs,
339342
pricing_spec=pricing_spec,
340-
url_for=url_for,
343+
job_links=job_links,
341344
x_simcore_parent_project_uuid=parent_project_uuid,
342345
x_simcore_parent_node_id=parent_node_id,
343346
)
@@ -388,6 +391,7 @@ async def map_function( # noqa: PLR0913
388391
function_jobs_service: Annotated[
389392
FunctionJobService, Depends(get_function_job_service)
390393
],
394+
function_service: Annotated[FunctionService, Depends(get_function_service)],
391395
x_simcore_parent_project_uuid: Annotated[ProjectID | Literal["null"], Header()],
392396
x_simcore_parent_node_id: Annotated[NodeID | Literal["null"], Header()],
393397
) -> RegisteredFunctionJobCollection:
@@ -404,11 +408,13 @@ async def map_function( # noqa: PLR0913
404408
)
405409
pricing_spec = JobPricingSpecification.create_from_headers(request.headers)
406410

411+
job_links = await function_service.get_function_job_links(to_run_function, url_for)
412+
407413
return await function_jobs_service.map_function(
408414
function=to_run_function,
409415
function_inputs_list=function_inputs_list,
410416
pricing_spec=pricing_spec,
411-
url_for=url_for,
417+
job_links=job_links,
412418
x_simcore_parent_project_uuid=parent_project_uuid,
413419
x_simcore_parent_node_id=parent_node_id,
414420
)

0 commit comments

Comments
 (0)