Skip to content

Commit 6314ffe

Browse files
committed
Return the created_at data of registered function api objects
1 parent d26df1e commit 6314ffe

File tree

9 files changed

+814
-725
lines changed

9 files changed

+814
-725
lines changed

packages/models-library/src/models_library/functions.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import datetime
12
from collections.abc import Mapping
23
from enum import Enum
34
from typing import Annotated, Any, Literal, TypeAlias
@@ -93,6 +94,7 @@ class FunctionBase(BaseModel):
9394

9495
class RegisteredFunctionBase(FunctionBase):
9596
uid: FunctionID
97+
created_at: datetime.datetime
9698

9799

98100
class ProjectFunction(FunctionBase):
@@ -149,6 +151,7 @@ class FunctionJobBase(BaseModel):
149151

150152
class RegisteredFunctionJobBase(FunctionJobBase):
151153
uid: FunctionJobID
154+
created_at: datetime.datetime
152155

153156

154157
class ProjectFunctionJob(FunctionJobBase):
@@ -204,6 +207,7 @@ class FunctionJobCollection(BaseModel):
204207

205208
class RegisteredFunctionJobCollection(FunctionJobCollection):
206209
uid: FunctionJobCollectionID
210+
created_at: datetime.datetime
207211

208212

209213
class FunctionJobCollectionStatus(BaseModel):
@@ -222,6 +226,7 @@ class FunctionJobDB(BaseModel):
222226

223227
class RegisteredFunctionJobDB(FunctionJobDB):
224228
uuid: FunctionJobID
229+
created: datetime.datetime
225230

226231

227232
class FunctionDB(BaseModel):
@@ -236,6 +241,7 @@ class FunctionDB(BaseModel):
236241

237242
class RegisteredFunctionDB(FunctionDB):
238243
uuid: FunctionID
244+
created: datetime.datetime
239245

240246

241247
class FunctionJobCollectionDB(BaseModel):
@@ -245,6 +251,7 @@ class FunctionJobCollectionDB(BaseModel):
245251

246252
class RegisteredFunctionJobCollectionDB(FunctionJobCollectionDB):
247253
uuid: FunctionJobCollectionID
254+
created: datetime.datetime
248255

249256

250257
class FunctionIDString(ConstrainedStr):

services/api-server/tests/unit/api_functions/conftest.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# pylint: disable=no-self-use
66
# pylint: disable=cyclic-import
77

8+
import datetime
89
from collections.abc import Callable
910
from typing import Any
1011
from uuid import uuid4
@@ -119,7 +120,13 @@ def mock_function(
119120

120121
@pytest.fixture
121122
def mock_registered_function(mock_function: Function) -> RegisteredFunction:
122-
return RegisteredProjectFunction(**{**mock_function.dict(), "uid": str(uuid4())})
123+
return RegisteredProjectFunction(
124+
**{
125+
**mock_function.dict(),
126+
"uid": str(uuid4()),
127+
"created_at": datetime.datetime.now(datetime.UTC),
128+
}
129+
)
123130

124131

125132
@pytest.fixture
@@ -141,7 +148,11 @@ def mock_registered_function_job(
141148
mock_function_job: FunctionJob,
142149
) -> RegisteredFunctionJob:
143150
return RegisteredProjectFunctionJob(
144-
**{**mock_function_job.dict(), "uid": str(uuid4())}
151+
**{
152+
**mock_function_job.dict(),
153+
"uid": str(uuid4()),
154+
"created_at": datetime.datetime.now(datetime.UTC),
155+
}
145156
)
146157

147158

@@ -165,7 +176,11 @@ def mock_registered_function_job_collection(
165176
mock_function_job_collection: FunctionJobCollection,
166177
) -> RegisteredFunctionJobCollection:
167178
return RegisteredFunctionJobCollection(
168-
**{**mock_function_job_collection.model_dump(), "uid": str(uuid4())}
179+
**{
180+
**mock_function_job_collection.model_dump(),
181+
"uid": str(uuid4()),
182+
"created_at": datetime.datetime.now(datetime.UTC),
183+
}
169184
)
170185

171186

services/api-server/tests/unit/api_functions/test_api_routers_functions.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# pylint: disable=unused-argument
22
# pylint: disable=redefined-outer-name
33

4+
import datetime
45
from collections.abc import Callable
56
from typing import Any
67
from uuid import uuid4
@@ -27,20 +28,19 @@ async def test_register_function(
2728
mock_handler_in_functions_rpc_interface: Callable[[str, Any], None],
2829
mock_function: ProjectFunction,
2930
auth: httpx.BasicAuth,
31+
mock_registered_function: RegisteredProjectFunction,
3032
) -> None:
31-
registered_function = RegisteredProjectFunction(
32-
**{**mock_function.model_dump(), "uid": str(uuid4())}
33+
mock_handler_in_functions_rpc_interface(
34+
"register_function", mock_registered_function
3335
)
34-
35-
mock_handler_in_functions_rpc_interface("register_function", registered_function)
3636
response = await client.post(
3737
f"{API_VTAG}/functions", json=mock_function.model_dump(mode="json"), auth=auth
3838
)
3939
assert response.status_code == status.HTTP_200_OK
4040
data = response.json()
4141
returned_function = RegisteredProjectFunction.model_validate(data)
4242
assert returned_function.uid is not None
43-
assert returned_function == registered_function
43+
assert returned_function == mock_registered_function
4444

4545

4646
async def test_register_function_invalid(
@@ -391,6 +391,7 @@ async def test_register_function_job_collection(
391391
{
392392
**mock_function_job_collection.model_dump(),
393393
"uid": str(uuid4()),
394+
"created_at": datetime.datetime.now(datetime.UTC),
394395
}
395396
)
396397
)
@@ -425,6 +426,7 @@ async def test_get_function_job_collection(
425426
"title": "Test Collection",
426427
"description": "A test function job collection",
427428
"job_ids": [str(uuid4()), str(uuid4())],
429+
"created_at": datetime.datetime.now(datetime.UTC),
428430
}
429431
)
430432
)
@@ -456,6 +458,7 @@ async def test_list_function_job_collections(
456458
"title": "Test Collection",
457459
"description": "A test function job collection",
458460
"job_ids": [str(uuid4()), str(uuid4())],
461+
"created_at": datetime.datetime.now(datetime.UTC),
459462
}
460463
)
461464
)

services/web/server/src/simcore_service_webserver/functions/_functions_service.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ async def register_function_job_collection(
112112
title=registered_function_job_collection.title,
113113
description=registered_function_job_collection.description,
114114
job_ids=registered_job_ids,
115+
created_at=registered_function_job_collection.created,
115116
)
116117

117118

@@ -174,6 +175,7 @@ async def get_function_job_collection(
174175
title=returned_function_job_collection.title,
175176
description=returned_function_job_collection.description,
176177
job_ids=returned_job_ids,
178+
created_at=returned_function_job_collection.created,
177179
)
178180

179181

@@ -248,6 +250,7 @@ async def list_function_job_collections(
248250
title=function_job_collection.title,
249251
description=function_job_collection.description,
250252
job_ids=job_ids,
253+
created_at=function_job_collection.created,
251254
)
252255
for function_job_collection, job_ids in returned_function_job_collections
253256
], page
@@ -372,6 +375,7 @@ async def find_cached_function_jobs(
372375
project_job_id=returned_function_job.class_specific_data[
373376
"project_job_id"
374377
],
378+
created_at=returned_function_job.created,
375379
)
376380
)
377381
elif returned_function_job.function_class == FunctionClass.SOLVER:
@@ -386,6 +390,7 @@ async def find_cached_function_jobs(
386390
solver_job_id=returned_function_job.class_specific_data[
387391
"solver_job_id"
388392
],
393+
created_at=returned_function_job.created,
389394
)
390395
)
391396
else:
@@ -442,6 +447,7 @@ def _decode_function(
442447
output_schema=function.output_schema,
443448
project_id=function.class_specific_data["project_id"],
444449
default_inputs=function.default_inputs,
450+
created_at=function.created,
445451
)
446452

447453
if function.function_class == FunctionClass.SOLVER:
@@ -454,6 +460,7 @@ def _decode_function(
454460
solver_key=function.class_specific_data["solver_key"],
455461
solver_version=function.class_specific_data["solver_version"],
456462
default_inputs=function.default_inputs,
463+
created_at=function.created,
457464
)
458465

459466
raise UnsupportedFunctionClassError(function_class=function.function_class)
@@ -530,6 +537,7 @@ def _decode_functionjob(
530537
inputs=functionjob_db.inputs,
531538
outputs=functionjob_db.outputs,
532539
project_job_id=functionjob_db.class_specific_data["project_job_id"],
540+
created_at=functionjob_db.created,
533541
)
534542

535543
if functionjob_db.function_class == FunctionClass.SOLVER:
@@ -541,6 +549,7 @@ def _decode_functionjob(
541549
inputs=functionjob_db.inputs,
542550
outputs=functionjob_db.outputs,
543551
solver_job_id=functionjob_db.class_specific_data["solver_job_id"],
552+
created_at=functionjob_db.created,
544553
)
545554

546555
raise UnsupportedFunctionJobClassError(

services/web/server/tests/unit/with_dbs/04/functions_rpc/conftest.py

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,17 @@
33
# pylint:disable=redefined-outer-name
44

55

6-
from collections.abc import AsyncIterator
6+
from collections.abc import AsyncIterator, Awaitable, Callable
7+
from uuid import uuid4
78

89
import pytest
910
from aiohttp.test_utils import TestClient
11+
from models_library.api_schemas_webserver.functions import (
12+
Function,
13+
JSONFunctionInputSchema,
14+
JSONFunctionOutputSchema,
15+
ProjectFunction,
16+
)
1017
from models_library.products import ProductName
1118
from pytest_simcore.helpers.monkeypatch_envs import setenvs_from_dict
1219
from pytest_simcore.helpers.typing_env import EnvVarsDict
@@ -15,21 +22,64 @@
1522
from servicelib.rabbitmq.rpc_interfaces.webserver.functions import (
1623
functions_rpc_interface as functions_rpc,
1724
)
25+
from settings_library.rabbit import RabbitSettings
26+
from simcore_service_webserver.application_settings import ApplicationSettings
1827

1928

2029
@pytest.fixture
2130
def app_environment(
31+
rabbit_service: RabbitSettings,
2232
app_environment: EnvVarsDict,
2333
monkeypatch: pytest.MonkeyPatch,
24-
):
25-
return setenvs_from_dict(
34+
) -> EnvVarsDict:
35+
new_envs = setenvs_from_dict(
2636
monkeypatch,
2737
{
28-
**app_environment, # WARNING: AFTER env_devel_dict because HOST are set to 127.0.0.1 in here
38+
**app_environment,
39+
"RABBIT_HOST": rabbit_service.RABBIT_HOST,
40+
"RABBIT_PORT": f"{rabbit_service.RABBIT_PORT}",
41+
"RABBIT_USER": rabbit_service.RABBIT_USER,
42+
"RABBIT_SECURE": f"{rabbit_service.RABBIT_SECURE}",
43+
"RABBIT_PASSWORD": rabbit_service.RABBIT_PASSWORD.get_secret_value(),
44+
"WEBSERVER_DEV_FEATURES_ENABLED": "1",
2945
"WEBSERVER_FUNCTIONS": "1",
3046
},
3147
)
3248

49+
settings = ApplicationSettings.create_from_envs()
50+
assert settings.WEBSERVER_RABBITMQ
51+
52+
return new_envs
53+
54+
55+
@pytest.fixture
56+
async def rpc_client(
57+
rabbitmq_rpc_client: Callable[[str], Awaitable[RabbitMQRPCClient]],
58+
) -> RabbitMQRPCClient:
59+
return await rabbitmq_rpc_client("client")
60+
61+
62+
@pytest.fixture
63+
def mock_function() -> Function:
64+
return ProjectFunction(
65+
title="Test Function",
66+
description="A test function",
67+
input_schema=JSONFunctionInputSchema(
68+
schema_content={
69+
"type": "object",
70+
"properties": {"input1": {"type": "string"}},
71+
}
72+
),
73+
output_schema=JSONFunctionOutputSchema(
74+
schema_content={
75+
"type": "object",
76+
"properties": {"output1": {"type": "string"}},
77+
}
78+
),
79+
project_id=uuid4(),
80+
default_inputs=None,
81+
)
82+
3383

3484
@pytest.fixture
3585
async def other_logged_user(

0 commit comments

Comments
 (0)