Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c836380
Pagination endpoint jobs
wvangeit Aug 4, 2025
77ab078
Merge branch 'master' into add_function_job_filters
wvangeit Aug 4, 2025
065cccd
Test filter function jobs by ids
wvangeit Aug 4, 2025
48575cb
Merge branch 'master' into add_function_job_filters
wvangeit Aug 4, 2025
051eb45
Add changelog messages
wvangeit Aug 4, 2025
0697c65
Update openapi specs
wvangeit Aug 4, 2025
79fc1c7
Merge branch 'master' into add_function_job_filters
wvangeit Aug 5, 2025
a2cfda0
Merge branch 'master' into add_function_job_filters
wvangeit Aug 5, 2025
4d65e86
Fix linting
wvangeit Aug 5, 2025
91d92b8
Merge branch 'add_function_job_filters' of github.com:wvangeit/osparc…
wvangeit Aug 5, 2025
3390efe
Revert studies_jobs change
wvangeit Aug 5, 2025
283427e
Fix job id type
wvangeit Aug 5, 2025
58829d9
Fix job type in test
wvangeit Aug 5, 2025
b455ca7
Fix import in test
wvangeit Aug 5, 2025
34db9ca
Make job listing test more complex
wvangeit Aug 6, 2025
07ad50e
Add an AbstractPage return type
wvangeit Aug 6, 2025
23e5027
Add more AbstractPage return values in functions api
wvangeit Aug 6, 2025
8bba5bd
Merge branch 'master' into add_function_job_filters
wvangeit Aug 6, 2025
cb78209
Update openapi specs
wvangeit Aug 6, 2025
faf78d4
Add 2 extra function rpc tests
wvangeit Aug 7, 2025
87ac9b2
Merge branch 'master' into add_function_job_filters
wvangeit Aug 7, 2025
9dfe883
Fix version strings
wvangeit Aug 7, 2025
1786ca1
services/api-server version: 0.10.0 → 0.11.0
wvangeit Aug 7, 2025
b6bb8e8
Mention new version in more files
wvangeit Aug 7, 2025
f5faca0
Update openapi specs
wvangeit Aug 7, 2025
18de9fa
Merge branch 'master' into add_function_job_filters
wvangeit Aug 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ async def list_function_jobs(
pagination_limit: int,
pagination_offset: int,
filter_by_function_id: FunctionID | None = None,
filter_by_function_job_ids: list[FunctionJobID] | None = None,
filter_by_function_job_collection_id: FunctionJobCollectionID | None = None,
) -> tuple[list[RegisteredFunctionJob], PageMetaInfoLimitOffset]:
result: tuple[list[RegisteredFunctionJob], PageMetaInfoLimitOffset] = (
await rabbitmq_rpc_client.request(
Expand All @@ -170,6 +172,8 @@ async def list_function_jobs(
pagination_offset=pagination_offset,
pagination_limit=pagination_limit,
filter_by_function_id=filter_by_function_id,
filter_by_function_job_ids=filter_by_function_job_ids,
filter_by_function_job_collection_id=filter_by_function_job_collection_id,
)
)
return TypeAdapter(
Expand Down
2 changes: 1 addition & 1 deletion services/api-server/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.10.0
0.11.0
229 changes: 226 additions & 3 deletions services/api-server/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"info": {
"title": "osparc.io public API",
"description": "osparc-simcore public API specifications",
"version": "0.10.0"
"version": "0.11.0"
},
"paths": {
"/v0/meta": {
Expand Down Expand Up @@ -5305,7 +5305,7 @@
"function_jobs"
],
"summary": "List Function Jobs",
"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",
"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`",
"operationId": "list_function_jobs",
"security": [
{
Expand Down Expand Up @@ -5335,6 +5335,66 @@
"default": 0,
"title": "Offset"
}
},
{
"name": "function_id",
"in": "query",
"required": false,
"schema": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"description": "Filter by function ID pattern",
"title": "Function Id"
},
"description": "Filter by function ID pattern"
},
{
"name": "function_job_ids",
"in": "query",
"required": false,
"schema": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
},
{
"type": "null"
}
],
"description": "Filter by function job IDs",
"title": "Function Job Ids"
},
"description": "Filter by function job IDs"
},
{
"name": "function_job_collection_id",
"in": "query",
"required": false,
"schema": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"description": "Filter by function job collection ID",
"title": "Function Job Collection Id"
},
"description": "Filter by function job collection ID"
}
],
"responses": {
Expand Down Expand Up @@ -5710,7 +5770,7 @@
"function_jobs"
],
"summary": "Get Function Job Logs Task",
"description": "Get function job logs task\n\nNew in *version 0.10-rc1*",
"description": "Get function job logs task\n\nNew in *version 0.11.0*",
"operationId": "get_function_job_logs_task",
"security": [
{
Expand Down Expand Up @@ -6082,6 +6142,169 @@
}
}
},
"/v0/function_job_collections/{function_job_collection_id}/function_jobs/page": {
"get": {
"tags": [
"function_job_collections"
],
"summary": "Function Job Collection List Function Jobs Page",
"description": "Get the function jobs in function job collection\n\nNew in *version 0.11.0*",
"operationId": "function_job_collection_list_function_jobs_page",
"security": [
{
"HTTPBasic": []
}
],
"parameters": [
{
"name": "function_job_collection_id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid",
"title": "Function Job Collection Id"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"schema": {
"type": "integer",
"maximum": 50,
"minimum": 1,
"default": 20,
"title": "Limit"
}
},
{
"name": "offset",
"in": "query",
"required": false,
"schema": {
"type": "integer",
"minimum": 0,
"default": 0,
"title": "Offset"
}
}
],
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Page_Annotated_Union_RegisteredProjectFunctionJob__RegisteredPythonCodeFunctionJob__RegisteredSolverFunctionJob___FieldInfo_annotation_NoneType__required_True__discriminator__function_class____"
}
}
}
},
"404": {
"description": "Function job collection not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorGet"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
}
},
"/v0/function_job_collections/{function_job_collection_id}/function_jobs/list": {
"get": {
"tags": [
"function_job_collections"
],
"summary": "Function Job Collection List Function Jobs List",
"description": "Get the function jobs in function job collection\n\nNew in *version 0.11.0*",
"operationId": "function_job_collection_list_function_jobs_list",
"security": [
{
"HTTPBasic": []
}
],
"parameters": [
{
"name": "function_job_collection_id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid",
"title": "Function Job Collection Id"
}
}
],
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/components/schemas/RegisteredProjectFunctionJob"
},
{
"$ref": "#/components/schemas/RegisteredPythonCodeFunctionJob"
},
{
"$ref": "#/components/schemas/RegisteredSolverFunctionJob"
}
],
"discriminator": {
"propertyName": "function_class",
"mapping": {
"PROJECT": "#/components/schemas/RegisteredProjectFunctionJob",
"PYTHON_CODE": "#/components/schemas/RegisteredPythonCodeFunctionJob",
"SOLVER": "#/components/schemas/RegisteredSolverFunctionJob"
}
}
},
"title": "Response Function Job Collection List Function Jobs List V0 Function Job Collections Function Job Collection Id Function Jobs List Get"
}
}
}
},
"404": {
"description": "Function job collection not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorGet"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
}
},
"/v0/function_job_collections/{function_job_collection_id}/status": {
"get": {
"tags": [
Expand Down
6 changes: 3 additions & 3 deletions services/api-server/setup.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.10.0
current_version = 0.11.0
commit = True
message = services/api-server version: {current_version} → {new_version}
tag = False
Expand All @@ -11,12 +11,12 @@ commit_args = --no-verify
asyncio_mode = auto
asyncio_default_fixture_loop_scope = function
addopts = --strict-markers
markers =
markers =
slow: marks tests as slow (deselect with '-m "not slow"')
acceptance_test: "marks tests as 'acceptance tests' i.e. does the system do what the user expects? Typically those are workflows."
testit: "marks test to run during development"

[mypy]
plugins =
plugins =
pydantic.mypy
sqlalchemy.ext.mypy.plugin
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from dataclasses import dataclass

from common_library.exclude import as_dict_exclude_none
from models_library.functions import (
FunctionID,
FunctionJobCollectionID,
FunctionJobID,
RegisteredFunctionJob,
)
from models_library.products import ProductName
from models_library.rest_pagination import PageMetaInfoLimitOffset, PageOffsetInt
from models_library.rpc_pagination import PageLimitInt
from models_library.users import UserID
from simcore_service_api_server.services_rpc.wb_api_server import WbApiRpcClient


@dataclass(frozen=True, kw_only=True)
class FunctionJobService:
user_id: UserID
product_name: ProductName
_web_rpc_client: WbApiRpcClient

async def list_function_jobs(
self,
*,
filter_by_function_id: FunctionID | None = None,
filter_by_function_job_ids: list[FunctionJobID] | None = None,
filter_by_function_job_collection_id: FunctionJobCollectionID | None = None,
pagination_offset: PageOffsetInt | None = None,
pagination_limit: PageLimitInt | None = None,
) -> tuple[list[RegisteredFunctionJob], PageMetaInfoLimitOffset]:
"""Lists all function jobs for a user with pagination"""

pagination_kwargs = as_dict_exclude_none(
pagination_offset=pagination_offset, pagination_limit=pagination_limit
)

return await self._web_rpc_client.list_function_jobs(
user_id=self.user_id,
product_name=self.product_name,
filter_by_function_id=filter_by_function_id,
filter_by_function_job_ids=filter_by_function_job_ids,
filter_by_function_job_collection_id=filter_by_function_job_collection_id,
**pagination_kwargs,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from dataclasses import dataclass

from common_library.exclude import as_dict_exclude_none
from models_library.functions import RegisteredFunction
from models_library.products import ProductName
from models_library.rest_pagination import (
MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE,
PageMetaInfoLimitOffset,
PageOffsetInt,
)
from models_library.rpc_pagination import PageLimitInt
from models_library.users import UserID
from simcore_service_api_server.services_rpc.wb_api_server import WbApiRpcClient

DEFAULT_PAGINATION_LIMIT = MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE - 1


@dataclass(frozen=True, kw_only=True)
class FunctionService:
user_id: UserID
product_name: ProductName
_web_rpc_client: WbApiRpcClient

async def list_functions(
self,
*,
pagination_offset: PageOffsetInt | None = None,
pagination_limit: PageLimitInt | None = None,
) -> tuple[list[RegisteredFunction], PageMetaInfoLimitOffset]:
"""Lists all functions for a user with pagination"""

pagination_kwargs = as_dict_exclude_none(
pagination_offset=pagination_offset, pagination_limit=pagination_limit
)

return await self._web_rpc_client.list_functions(
user_id=self.user_id,
product_name=self.product_name,
**pagination_kwargs,
)
Loading
Loading