Skip to content

Commit 555a5a9

Browse files
committed
First batch of changes requested by GHK for functions API
1 parent 0b1e491 commit 555a5a9

File tree

7 files changed

+199
-387
lines changed

7 files changed

+199
-387
lines changed

packages/models-library/src/models_library/api_schemas_webserver/functions_wb_schema.py

Lines changed: 22 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from typing import Annotated, Any, Literal, TypeAlias
44
from uuid import UUID
55

6+
from common_library.errors_classes import OsparcErrorMixin
67
from models_library import projects
78
from models_library.services_types import ServiceKey, ServiceVersion
89
from pydantic import BaseModel, Field
@@ -66,6 +67,7 @@ class FunctionClass(str, Enum):
6667

6768

6869
# TODO, use InputTypes here, but api is throwing weird errors and asking for dict for elements # noqa: FIX002
70+
# see here https://github.com/ITISFoundation/osparc-simcore/issues/7659
6971
FunctionInputs: TypeAlias = dict[str, Any] | None
7072

7173
FunctionInputsList: TypeAlias = list[FunctionInputs]
@@ -203,86 +205,52 @@ class FunctionJobCollectionStatus(BaseModel):
203205
status: list[str]
204206

205207

206-
class FunctionIDNotFoundError(Exception):
208+
class FunctionBaseError(OsparcErrorMixin, Exception):
209+
pass
210+
211+
212+
class FunctionIDNotFoundError(FunctionBaseError):
207213
"""Exception raised when a function is not found"""
208214

209-
def __init__(self, function_id: FunctionID):
210-
self.function_id = function_id
211-
super().__init__(f"Function {function_id} not found")
215+
msg_template: str = "Function {function_id} not found"
212216

213217

214-
class FunctionJobIDNotFoundError(Exception):
218+
class FunctionJobIDNotFoundError(FunctionBaseError):
215219
"""Exception raised when a function job is not found"""
216220

217-
def __init__(self, function_job_id: FunctionJobID):
218-
self.function_job_id = function_job_id
219-
super().__init__(f"Function job {function_job_id} not found")
221+
msg_template: str = "Function job {function_job_id} not found"
220222

221223

222-
class FunctionJobCollectionIDNotFoundError(Exception):
224+
class FunctionJobCollectionIDNotFoundError(FunctionBaseError):
223225
"""Exception raised when a function job collection is not found"""
224226

225-
def __init__(self, function_job_collection_id: FunctionJobCollectionID):
226-
self.function_job_collection_id = function_job_collection_id
227-
super().__init__(
228-
f"Function job collection {function_job_collection_id} not found"
229-
)
230-
231-
232-
class RegisterFunctionWithIDError(Exception):
233-
"""Exception raised when registering a function with a UID"""
234-
235-
def __init__(self):
236-
super().__init__("Cannot register Function with a UID")
237-
227+
msg_template: str = "Function job collection {function_job_collection_id} not found"
238228

239-
class RegisterFunctionJobWithIDError(Exception):
240-
"""Exception raised when registering a function job with a UID"""
241229

242-
def __init__(self):
243-
super().__init__("Cannot register FunctionJob with a UID")
244-
245-
246-
class RegisterFunctionJobCollectionWithIDError(Exception):
247-
"""Exception raised when registering a function job collection with a UID"""
248-
249-
def __init__(self):
250-
super().__init__("Cannot register FunctionJobCollection with a UID")
251-
252-
253-
class UnsupportedFunctionClassError(Exception):
230+
class UnsupportedFunctionClassError(FunctionBaseError):
254231
"""Exception raised when a function class is not supported"""
255232

256-
def __init__(self, function_class: str):
257-
self.function_class = function_class
258-
super().__init__(f"Function class {function_class} is not supported")
233+
msg_template: str = "Function class {function_class} is not supported"
259234

260235

261-
class UnsupportedFunctionJobClassError(Exception):
236+
class UnsupportedFunctionJobClassError(FunctionBaseError):
262237
"""Exception raised when a function job class is not supported"""
263238

264-
def __init__(self, function_job_class: str):
265-
self.function_job_class = function_job_class
266-
super().__init__(f"Function job class {function_job_class} is not supported")
239+
msg_template: str = "Function job class {function_job_class} is not supported"
267240

268241

269-
class UnsupportedFunctionFunctionJobClassCombinationError(Exception):
242+
class UnsupportedFunctionFunctionJobClassCombinationError(FunctionBaseError):
270243
"""Exception raised when a function / function job class combination is not supported"""
271244

272-
def __init__(self, function_class: str, function_job_class: str):
273-
self.function_class = function_class
274-
self.function_job_class = function_job_class
275-
super().__init__(
276-
f"Function class {function_class} and function job class {function_job_class} combination is not supported"
277-
)
245+
msg_template: str = (
246+
"Function class {function_class} and function job class {function_job_class} combination is not supported"
247+
)
278248

279249

280-
class FunctionInputsValidationError(Exception):
250+
class FunctionInputsValidationError(FunctionBaseError):
281251
"""Exception raised when validating function inputs"""
282252

283-
def __init__(self, error: str):
284-
self.errors = error
285-
super().__init__(f"Function inputs validation failed: {error}")
253+
msg_template: str = "Function inputs validation failed: {error}"
286254

287255

288256
class FunctionJobDB(BaseModel):

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

Lines changed: 46 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,14 @@ async def register_function(
3131
*,
3232
function: Function,
3333
) -> RegisteredFunction:
34-
result: RegisteredFunction = await rabbitmq_rpc_client.request(
34+
result = await rabbitmq_rpc_client.request(
3535
WEBSERVER_RPC_NAMESPACE,
3636
TypeAdapter(RPCMethodName).validate_python("register_function"),
3737
function=function,
3838
)
39-
TypeAdapter(Function).validate_python(result) # Validates the result as a Function
40-
return result
39+
return TypeAdapter(RegisteredFunction).validate_python(
40+
result
41+
) # Validates the result as a RegisteredFunction
4142

4243

4344
@log_decorator(_logger, level=logging.DEBUG)
@@ -46,13 +47,12 @@ async def get_function(
4647
*,
4748
function_id: FunctionID,
4849
) -> RegisteredFunction:
49-
result: RegisteredFunction = await rabbitmq_rpc_client.request(
50+
result = await rabbitmq_rpc_client.request(
5051
WEBSERVER_RPC_NAMESPACE,
5152
TypeAdapter(RPCMethodName).validate_python("get_function"),
5253
function_id=function_id,
5354
)
54-
TypeAdapter(Function).validate_python(result)
55-
return result
55+
return TypeAdapter(RegisteredFunction).validate_python(result)
5656

5757

5858
@log_decorator(_logger, level=logging.DEBUG)
@@ -61,13 +61,12 @@ async def get_function_input_schema(
6161
*,
6262
function_id: FunctionID,
6363
) -> FunctionInputSchema:
64-
result: FunctionInputSchema = await rabbitmq_rpc_client.request(
64+
result = await rabbitmq_rpc_client.request(
6565
WEBSERVER_RPC_NAMESPACE,
6666
TypeAdapter(RPCMethodName).validate_python("get_function_input_schema"),
6767
function_id=function_id,
6868
)
69-
TypeAdapter(FunctionInputSchema).validate_python(result)
70-
return result
69+
return TypeAdapter(FunctionInputSchema).validate_python(result)
7170

7271

7372
@log_decorator(_logger, level=logging.DEBUG)
@@ -76,13 +75,12 @@ async def get_function_output_schema(
7675
*,
7776
function_id: FunctionID,
7877
) -> FunctionOutputSchema:
79-
result: FunctionOutputSchema = await rabbitmq_rpc_client.request(
78+
result = await rabbitmq_rpc_client.request(
8079
WEBSERVER_RPC_NAMESPACE,
8180
TypeAdapter(RPCMethodName).validate_python("get_function_output_schema"),
8281
function_id=function_id,
8382
)
84-
TypeAdapter(FunctionOutputSchema).validate_python(result)
85-
return result
83+
return TypeAdapter(FunctionOutputSchema).validate_python(result)
8684

8785

8886
@log_decorator(_logger, level=logging.DEBUG)
@@ -91,7 +89,7 @@ async def delete_function(
9189
*,
9290
function_id: FunctionID,
9391
) -> None:
94-
result: None = await rabbitmq_rpc_client.request(
92+
result = await rabbitmq_rpc_client.request(
9593
WEBSERVER_RPC_NAMESPACE,
9694
TypeAdapter(RPCMethodName).validate_python("delete_function"),
9795
function_id=function_id,
@@ -138,12 +136,16 @@ async def list_function_jobs(
138136
pagination_limit=pagination_limit,
139137
)
140138
)
141-
assert isinstance(result, tuple)
142-
TypeAdapter(list[RegisteredFunctionJob]).validate_python(
143-
result[0]
144-
) # Validates the result as a list of RegisteredFunctionJobs
139+
assert isinstance(result, tuple) # nosec
140+
assert isinstance(result[0], list) # nosec
141+
assert all(
142+
TypeAdapter(RegisteredFunctionJob).validate_python(item) for item in result[0]
143+
) # nosec
145144
assert isinstance(result[1], PageMetaInfoLimitOffset) # nosec
146-
return result
145+
return (
146+
TypeAdapter(list[RegisteredFunctionJob]).validate_python(result[0]),
147+
TypeAdapter(PageMetaInfoLimitOffset).validate_python(result[1]),
148+
)
147149

148150

149151
@log_decorator(_logger, level=logging.DEBUG)
@@ -153,20 +155,19 @@ async def list_function_job_collections(
153155
pagination_limit: int,
154156
pagination_offset: int,
155157
) -> tuple[list[RegisteredFunctionJobCollection], PageMetaInfoLimitOffset]:
156-
result: tuple[list[RegisteredFunctionJobCollection], PageMetaInfoLimitOffset] = (
157-
await rabbitmq_rpc_client.request(
158-
WEBSERVER_RPC_NAMESPACE,
159-
TypeAdapter(RPCMethodName).validate_python("list_function_job_collections"),
160-
pagination_offset=pagination_offset,
161-
pagination_limit=pagination_limit,
162-
)
158+
result = await rabbitmq_rpc_client.request(
159+
WEBSERVER_RPC_NAMESPACE,
160+
TypeAdapter(RPCMethodName).validate_python("list_function_job_collections"),
161+
pagination_offset=pagination_offset,
162+
pagination_limit=pagination_limit,
163163
)
164164
assert isinstance(result, tuple)
165-
TypeAdapter(list[RegisteredFunctionJobCollection]).validate_python(
166-
result[0]
167-
) # Validates the result as a list of RegisteredFunctionJobCollections
168-
assert isinstance(result[1], PageMetaInfoLimitOffset) # nosec
169-
return result
165+
return (
166+
TypeAdapter(list[RegisteredFunctionJobCollection]).validate_python(
167+
result[0]
168+
), # Validates the result as a list of RegisteredFunctionJobCollections
169+
TypeAdapter(PageMetaInfoLimitOffset).validate_python(result[1]), # nosec
170+
)
170171

171172

172173
@log_decorator(_logger, level=logging.DEBUG)
@@ -176,16 +177,15 @@ async def run_function(
176177
function_id: FunctionID,
177178
inputs: FunctionInputs,
178179
) -> RegisteredFunctionJob:
179-
result: RegisteredFunctionJob = await rabbitmq_rpc_client.request(
180+
result = await rabbitmq_rpc_client.request(
180181
WEBSERVER_RPC_NAMESPACE,
181182
TypeAdapter(RPCMethodName).validate_python("run_function"),
182183
function_id=function_id,
183184
inputs=inputs,
184185
)
185-
TypeAdapter(RegisteredFunctionJob).validate_python(
186+
return TypeAdapter(RegisteredFunctionJob).validate_python(
186187
result
187-
) # Validates the result as a FunctionJob
188-
return result
188+
) # Validates the result as a RegisteredFunctionJob
189189

190190

191191
@log_decorator(_logger, level=logging.DEBUG)
@@ -194,15 +194,14 @@ async def register_function_job(
194194
*,
195195
function_job: FunctionJob,
196196
) -> RegisteredFunctionJob:
197-
result: RegisteredFunctionJob = await rabbitmq_rpc_client.request(
197+
result = await rabbitmq_rpc_client.request(
198198
WEBSERVER_RPC_NAMESPACE,
199199
TypeAdapter(RPCMethodName).validate_python("register_function_job"),
200200
function_job=function_job,
201201
)
202-
TypeAdapter(RegisteredFunctionJob).validate_python(
202+
return TypeAdapter(RegisteredFunctionJob).validate_python(
203203
result
204204
) # Validates the result as a RegisteredFunctionJob
205-
return result
206205

207206

208207
@log_decorator(_logger, level=logging.DEBUG)
@@ -211,14 +210,13 @@ async def get_function_job(
211210
*,
212211
function_job_id: FunctionJobID,
213212
) -> RegisteredFunctionJob:
214-
result: RegisteredFunctionJob = await rabbitmq_rpc_client.request(
213+
result = await rabbitmq_rpc_client.request(
215214
WEBSERVER_RPC_NAMESPACE,
216215
TypeAdapter(RPCMethodName).validate_python("get_function_job"),
217216
function_job_id=function_job_id,
218217
)
219218

220-
TypeAdapter(RegisteredFunctionJob).validate_python(result)
221-
return result
219+
return TypeAdapter(RegisteredFunctionJob).validate_python(result)
222220

223221

224222
@log_decorator(_logger, level=logging.DEBUG)
@@ -233,7 +231,6 @@ async def delete_function_job(
233231
function_job_id=function_job_id,
234232
)
235233
assert result is None # nosec
236-
return result
237234

238235

239236
@log_decorator(_logger, level=logging.DEBUG)
@@ -243,16 +240,15 @@ async def find_cached_function_job(
243240
function_id: FunctionID,
244241
inputs: FunctionInputs,
245242
) -> RegisteredFunctionJob | None:
246-
result: RegisteredFunctionJob | None = await rabbitmq_rpc_client.request(
243+
result = await rabbitmq_rpc_client.request(
247244
WEBSERVER_RPC_NAMESPACE,
248245
TypeAdapter(RPCMethodName).validate_python("find_cached_function_job"),
249246
function_id=function_id,
250247
inputs=inputs,
251248
)
252249
if result is None:
253250
return None
254-
TypeAdapter(RegisteredFunctionJob).validate_python(result)
255-
return result
251+
return TypeAdapter(RegisteredFunctionJob).validate_python(result)
256252

257253

258254
@log_decorator(_logger, level=logging.DEBUG)
@@ -261,13 +257,12 @@ async def register_function_job_collection(
261257
*,
262258
function_job_collection: FunctionJobCollection,
263259
) -> RegisteredFunctionJobCollection:
264-
result: RegisteredFunctionJobCollection = await rabbitmq_rpc_client.request(
260+
result = await rabbitmq_rpc_client.request(
265261
WEBSERVER_RPC_NAMESPACE,
266262
TypeAdapter(RPCMethodName).validate_python("register_function_job_collection"),
267263
function_job_collection=function_job_collection,
268264
)
269-
TypeAdapter(RegisteredFunctionJobCollection).validate_python(result)
270-
return result
265+
return TypeAdapter(RegisteredFunctionJobCollection).validate_python(result)
271266

272267

273268
@log_decorator(_logger, level=logging.DEBUG)
@@ -276,13 +271,12 @@ async def get_function_job_collection(
276271
*,
277272
function_job_collection_id: FunctionJobCollectionID,
278273
) -> RegisteredFunctionJobCollection:
279-
result: RegisteredFunctionJobCollection = await rabbitmq_rpc_client.request(
274+
result = await rabbitmq_rpc_client.request(
280275
WEBSERVER_RPC_NAMESPACE,
281276
TypeAdapter(RPCMethodName).validate_python("get_function_job_collection"),
282277
function_job_collection_id=function_job_collection_id,
283278
)
284-
TypeAdapter(RegisteredFunctionJobCollection).validate_python(result)
285-
return result
279+
return TypeAdapter(RegisteredFunctionJobCollection).validate_python(result)
286280

287281

288282
@log_decorator(_logger, level=logging.DEBUG)
@@ -291,10 +285,9 @@ async def delete_function_job_collection(
291285
*,
292286
function_job_collection_id: FunctionJobCollectionID,
293287
) -> None:
294-
result: None = await rabbitmq_rpc_client.request(
288+
result = await rabbitmq_rpc_client.request(
295289
WEBSERVER_RPC_NAMESPACE,
296290
TypeAdapter(RPCMethodName).validate_python("delete_function_job_collection"),
297291
function_job_collection_id=function_job_collection_id,
298292
)
299-
assert result is None
300-
return result
293+
assert result is None # nosec

0 commit comments

Comments
 (0)