Skip to content

Commit 8548b0e

Browse files
authored
Add more function job filters 🎨 (#8187)
1 parent 19e3d7a commit 8548b0e

File tree

22 files changed

+742
-83
lines changed

22 files changed

+742
-83
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ async def list_function_jobs(
160160
pagination_limit: int,
161161
pagination_offset: int,
162162
filter_by_function_id: FunctionID | None = None,
163+
filter_by_function_job_ids: list[FunctionJobID] | None = None,
164+
filter_by_function_job_collection_id: FunctionJobCollectionID | None = None,
163165
) -> tuple[list[RegisteredFunctionJob], PageMetaInfoLimitOffset]:
164166
result: tuple[list[RegisteredFunctionJob], PageMetaInfoLimitOffset] = (
165167
await rabbitmq_rpc_client.request(
@@ -170,6 +172,8 @@ async def list_function_jobs(
170172
pagination_offset=pagination_offset,
171173
pagination_limit=pagination_limit,
172174
filter_by_function_id=filter_by_function_id,
175+
filter_by_function_job_ids=filter_by_function_job_ids,
176+
filter_by_function_job_collection_id=filter_by_function_job_collection_id,
173177
)
174178
)
175179
return TypeAdapter(

services/api-server/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.10.0
1+
0.11.0

services/api-server/openapi.json

Lines changed: 226 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"info": {
44
"title": "osparc.io public API",
55
"description": "osparc-simcore public API specifications",
6-
"version": "0.10.0"
6+
"version": "0.11.0"
77
},
88
"paths": {
99
"/v0/meta": {
@@ -5305,7 +5305,7 @@
53055305
"function_jobs"
53065306
],
53075307
"summary": "List Function Jobs",
5308-
"description": "List function jobs\n\nNew in *version 0.8.0*\n\nAdded in *version 0.9.0*: add `created_at` field in the registered function-related objects",
5308+
"description": "List function jobs\n\nNew in *version 0.8.0*\n\nAdded in *version 0.9.0*: add `created_at` field in the registered function-related objects\n\nAdded in *version 0.11.0*: add filter by `function_id`, `function_job_ids` and `function_job_collection_id`",
53095309
"operationId": "list_function_jobs",
53105310
"security": [
53115311
{
@@ -5335,6 +5335,66 @@
53355335
"default": 0,
53365336
"title": "Offset"
53375337
}
5338+
},
5339+
{
5340+
"name": "function_id",
5341+
"in": "query",
5342+
"required": false,
5343+
"schema": {
5344+
"anyOf": [
5345+
{
5346+
"type": "string",
5347+
"format": "uuid"
5348+
},
5349+
{
5350+
"type": "null"
5351+
}
5352+
],
5353+
"description": "Filter by function ID pattern",
5354+
"title": "Function Id"
5355+
},
5356+
"description": "Filter by function ID pattern"
5357+
},
5358+
{
5359+
"name": "function_job_ids",
5360+
"in": "query",
5361+
"required": false,
5362+
"schema": {
5363+
"anyOf": [
5364+
{
5365+
"type": "array",
5366+
"items": {
5367+
"type": "string",
5368+
"format": "uuid"
5369+
}
5370+
},
5371+
{
5372+
"type": "null"
5373+
}
5374+
],
5375+
"description": "Filter by function job IDs",
5376+
"title": "Function Job Ids"
5377+
},
5378+
"description": "Filter by function job IDs"
5379+
},
5380+
{
5381+
"name": "function_job_collection_id",
5382+
"in": "query",
5383+
"required": false,
5384+
"schema": {
5385+
"anyOf": [
5386+
{
5387+
"type": "string",
5388+
"format": "uuid"
5389+
},
5390+
{
5391+
"type": "null"
5392+
}
5393+
],
5394+
"description": "Filter by function job collection ID",
5395+
"title": "Function Job Collection Id"
5396+
},
5397+
"description": "Filter by function job collection ID"
53385398
}
53395399
],
53405400
"responses": {
@@ -5710,7 +5770,7 @@
57105770
"function_jobs"
57115771
],
57125772
"summary": "Get Function Job Logs Task",
5713-
"description": "Get function job logs task\n\nNew in *version 0.10-rc1*",
5773+
"description": "Get function job logs task\n\nNew in *version 0.11.0*",
57145774
"operationId": "get_function_job_logs_task",
57155775
"security": [
57165776
{
@@ -6082,6 +6142,169 @@
60826142
}
60836143
}
60846144
},
6145+
"/v0/function_job_collections/{function_job_collection_id}/function_jobs/page": {
6146+
"get": {
6147+
"tags": [
6148+
"function_job_collections"
6149+
],
6150+
"summary": "Function Job Collection List Function Jobs Page",
6151+
"description": "Get the function jobs in function job collection\n\nNew in *version 0.11.0*",
6152+
"operationId": "function_job_collection_list_function_jobs_page",
6153+
"security": [
6154+
{
6155+
"HTTPBasic": []
6156+
}
6157+
],
6158+
"parameters": [
6159+
{
6160+
"name": "function_job_collection_id",
6161+
"in": "path",
6162+
"required": true,
6163+
"schema": {
6164+
"type": "string",
6165+
"format": "uuid",
6166+
"title": "Function Job Collection Id"
6167+
}
6168+
},
6169+
{
6170+
"name": "limit",
6171+
"in": "query",
6172+
"required": false,
6173+
"schema": {
6174+
"type": "integer",
6175+
"maximum": 50,
6176+
"minimum": 1,
6177+
"default": 20,
6178+
"title": "Limit"
6179+
}
6180+
},
6181+
{
6182+
"name": "offset",
6183+
"in": "query",
6184+
"required": false,
6185+
"schema": {
6186+
"type": "integer",
6187+
"minimum": 0,
6188+
"default": 0,
6189+
"title": "Offset"
6190+
}
6191+
}
6192+
],
6193+
"responses": {
6194+
"200": {
6195+
"description": "Successful Response",
6196+
"content": {
6197+
"application/json": {
6198+
"schema": {
6199+
"$ref": "#/components/schemas/Page_Annotated_Union_RegisteredProjectFunctionJob__RegisteredPythonCodeFunctionJob__RegisteredSolverFunctionJob___FieldInfo_annotation_NoneType__required_True__discriminator__function_class____"
6200+
}
6201+
}
6202+
}
6203+
},
6204+
"404": {
6205+
"description": "Function job collection not found",
6206+
"content": {
6207+
"application/json": {
6208+
"schema": {
6209+
"$ref": "#/components/schemas/ErrorGet"
6210+
}
6211+
}
6212+
}
6213+
},
6214+
"422": {
6215+
"description": "Validation Error",
6216+
"content": {
6217+
"application/json": {
6218+
"schema": {
6219+
"$ref": "#/components/schemas/HTTPValidationError"
6220+
}
6221+
}
6222+
}
6223+
}
6224+
}
6225+
}
6226+
},
6227+
"/v0/function_job_collections/{function_job_collection_id}/function_jobs/list": {
6228+
"get": {
6229+
"tags": [
6230+
"function_job_collections"
6231+
],
6232+
"summary": "Function Job Collection List Function Jobs List",
6233+
"description": "Get the function jobs in function job collection\n\nNew in *version 0.11.0*",
6234+
"operationId": "function_job_collection_list_function_jobs_list",
6235+
"security": [
6236+
{
6237+
"HTTPBasic": []
6238+
}
6239+
],
6240+
"parameters": [
6241+
{
6242+
"name": "function_job_collection_id",
6243+
"in": "path",
6244+
"required": true,
6245+
"schema": {
6246+
"type": "string",
6247+
"format": "uuid",
6248+
"title": "Function Job Collection Id"
6249+
}
6250+
}
6251+
],
6252+
"responses": {
6253+
"200": {
6254+
"description": "Successful Response",
6255+
"content": {
6256+
"application/json": {
6257+
"schema": {
6258+
"type": "array",
6259+
"items": {
6260+
"oneOf": [
6261+
{
6262+
"$ref": "#/components/schemas/RegisteredProjectFunctionJob"
6263+
},
6264+
{
6265+
"$ref": "#/components/schemas/RegisteredPythonCodeFunctionJob"
6266+
},
6267+
{
6268+
"$ref": "#/components/schemas/RegisteredSolverFunctionJob"
6269+
}
6270+
],
6271+
"discriminator": {
6272+
"propertyName": "function_class",
6273+
"mapping": {
6274+
"PROJECT": "#/components/schemas/RegisteredProjectFunctionJob",
6275+
"PYTHON_CODE": "#/components/schemas/RegisteredPythonCodeFunctionJob",
6276+
"SOLVER": "#/components/schemas/RegisteredSolverFunctionJob"
6277+
}
6278+
}
6279+
},
6280+
"title": "Response Function Job Collection List Function Jobs List V0 Function Job Collections Function Job Collection Id Function Jobs List Get"
6281+
}
6282+
}
6283+
}
6284+
},
6285+
"404": {
6286+
"description": "Function job collection not found",
6287+
"content": {
6288+
"application/json": {
6289+
"schema": {
6290+
"$ref": "#/components/schemas/ErrorGet"
6291+
}
6292+
}
6293+
}
6294+
},
6295+
"422": {
6296+
"description": "Validation Error",
6297+
"content": {
6298+
"application/json": {
6299+
"schema": {
6300+
"$ref": "#/components/schemas/HTTPValidationError"
6301+
}
6302+
}
6303+
}
6304+
}
6305+
}
6306+
}
6307+
},
60856308
"/v0/function_job_collections/{function_job_collection_id}/status": {
60866309
"get": {
60876310
"tags": [

services/api-server/setup.cfg

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.10.0
2+
current_version = 0.11.0
33
commit = True
44
message = services/api-server version: {current_version} → {new_version}
55
tag = False
@@ -11,12 +11,12 @@ commit_args = --no-verify
1111
asyncio_mode = auto
1212
asyncio_default_fixture_loop_scope = function
1313
addopts = --strict-markers
14-
markers =
14+
markers =
1515
slow: marks tests as slow (deselect with '-m "not slow"')
1616
acceptance_test: "marks tests as 'acceptance tests' i.e. does the system do what the user expects? Typically those are workflows."
1717
testit: "marks test to run during development"
1818

1919
[mypy]
20-
plugins =
20+
plugins =
2121
pydantic.mypy
2222
sqlalchemy.ext.mypy.plugin
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from dataclasses import dataclass
2+
3+
from common_library.exclude import as_dict_exclude_none
4+
from models_library.functions import (
5+
FunctionID,
6+
FunctionJobCollectionID,
7+
FunctionJobID,
8+
RegisteredFunctionJob,
9+
)
10+
from models_library.products import ProductName
11+
from models_library.rest_pagination import PageMetaInfoLimitOffset, PageOffsetInt
12+
from models_library.rpc_pagination import PageLimitInt
13+
from models_library.users import UserID
14+
from simcore_service_api_server.services_rpc.wb_api_server import WbApiRpcClient
15+
16+
17+
@dataclass(frozen=True, kw_only=True)
18+
class FunctionJobService:
19+
user_id: UserID
20+
product_name: ProductName
21+
_web_rpc_client: WbApiRpcClient
22+
23+
async def list_function_jobs(
24+
self,
25+
*,
26+
filter_by_function_id: FunctionID | None = None,
27+
filter_by_function_job_ids: list[FunctionJobID] | None = None,
28+
filter_by_function_job_collection_id: FunctionJobCollectionID | None = None,
29+
pagination_offset: PageOffsetInt | None = None,
30+
pagination_limit: PageLimitInt | None = None,
31+
) -> tuple[list[RegisteredFunctionJob], PageMetaInfoLimitOffset]:
32+
"""Lists all function jobs for a user with pagination"""
33+
34+
pagination_kwargs = as_dict_exclude_none(
35+
pagination_offset=pagination_offset, pagination_limit=pagination_limit
36+
)
37+
38+
return await self._web_rpc_client.list_function_jobs(
39+
user_id=self.user_id,
40+
product_name=self.product_name,
41+
filter_by_function_id=filter_by_function_id,
42+
filter_by_function_job_ids=filter_by_function_job_ids,
43+
filter_by_function_job_collection_id=filter_by_function_job_collection_id,
44+
**pagination_kwargs,
45+
)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from dataclasses import dataclass
2+
3+
from common_library.exclude import as_dict_exclude_none
4+
from models_library.functions import RegisteredFunction
5+
from models_library.products import ProductName
6+
from models_library.rest_pagination import (
7+
MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE,
8+
PageMetaInfoLimitOffset,
9+
PageOffsetInt,
10+
)
11+
from models_library.rpc_pagination import PageLimitInt
12+
from models_library.users import UserID
13+
from simcore_service_api_server.services_rpc.wb_api_server import WbApiRpcClient
14+
15+
DEFAULT_PAGINATION_LIMIT = MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE - 1
16+
17+
18+
@dataclass(frozen=True, kw_only=True)
19+
class FunctionService:
20+
user_id: UserID
21+
product_name: ProductName
22+
_web_rpc_client: WbApiRpcClient
23+
24+
async def list_functions(
25+
self,
26+
*,
27+
pagination_offset: PageOffsetInt | None = None,
28+
pagination_limit: PageLimitInt | None = None,
29+
) -> tuple[list[RegisteredFunction], PageMetaInfoLimitOffset]:
30+
"""Lists all functions for a user with pagination"""
31+
32+
pagination_kwargs = as_dict_exclude_none(
33+
pagination_offset=pagination_offset, pagination_limit=pagination_limit
34+
)
35+
36+
return await self._web_rpc_client.list_functions(
37+
user_id=self.user_id,
38+
product_name=self.product_name,
39+
**pagination_kwargs,
40+
)

0 commit comments

Comments
 (0)