Skip to content

Commit db71616

Browse files
🎨 Improve listing task manager (add filter + and project name, project custom metadata fields) (#7661)
1 parent c49b779 commit db71616

File tree

16 files changed

+211
-28
lines changed

16 files changed

+211
-28
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,11 @@ class ComputationStarted(OutputSchemaWithoutCamelCase):
8181
class ComputationRunListQueryParams(
8282
PageQueryParameters,
8383
ComputationRunListOrderParams, # type: ignore[misc, valid-type]
84-
): ...
84+
):
85+
filter_only_running: bool = Field(
86+
default=False,
87+
description="If true, only running computations are returned",
88+
)
8589

8690

8791
class ComputationRunRestGet(OutputSchema):
@@ -92,6 +96,8 @@ class ComputationRunRestGet(OutputSchema):
9296
submitted_at: datetime
9397
started_at: datetime | None
9498
ended_at: datetime | None
99+
root_project_name: str
100+
project_custom_metadata: dict[str, Any]
95101

96102

97103
### Computation Task

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,17 @@ class ComputationTaskWithAttributes(BaseModel):
2222
# Attributes added by the webserver
2323
node_name: str
2424
osparc_credits: Decimal | None
25+
26+
27+
class ComputationRunWithAttributes(BaseModel):
28+
project_uuid: ProjectID
29+
iteration: int
30+
state: RunningState
31+
info: dict[str, Any]
32+
submitted_at: datetime
33+
started_at: datetime | None
34+
ended_at: datetime | None
35+
36+
# Attributes added by the webserver
37+
root_project_name: str
38+
project_custom_metadata: dict[str, Any]

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,18 @@ class RunningState(str, Enum):
3535
ABORTED = "ABORTED"
3636
WAITING_FOR_CLUSTER = "WAITING_FOR_CLUSTER"
3737

38-
def is_running(self) -> bool:
39-
return self in (
38+
@staticmethod
39+
def list_running_states() -> list["RunningState"]:
40+
return [
4041
RunningState.PUBLISHED,
4142
RunningState.PENDING,
4243
RunningState.WAITING_FOR_RESOURCES,
4344
RunningState.STARTED,
4445
RunningState.WAITING_FOR_CLUSTER,
45-
)
46+
]
47+
48+
def is_running(self) -> bool:
49+
return self in self.list_running_states()
4650

4751

4852
@unique

packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/director_v2/computations.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ async def list_computations_latest_iteration_page(
3333
*,
3434
product_name: ProductName,
3535
user_id: UserID,
36+
# filters
37+
filter_only_running: bool = False,
3638
# pagination
3739
offset: int = 0,
3840
limit: int = 20,
@@ -46,6 +48,7 @@ async def list_computations_latest_iteration_page(
4648
),
4749
product_name=product_name,
4850
user_id=user_id,
51+
filter_only_running=filter_only_running,
4952
offset=offset,
5053
limit=limit,
5154
order_by=order_by,

services/director-v2/src/simcore_service_director_v2/api/rpc/_computations.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ async def list_computations_latest_iteration_page(
2828
*,
2929
product_name: ProductName,
3030
user_id: UserID,
31+
# filters
32+
filter_only_running: bool = False,
3133
# pagination
3234
offset: int = 0,
3335
limit: int = 20,
@@ -39,6 +41,7 @@ async def list_computations_latest_iteration_page(
3941
await comp_runs_repo.list_for_user__only_latest_iterations(
4042
product_name=product_name,
4143
user_id=user_id,
44+
filter_only_running=filter_only_running,
4245
offset=offset,
4346
limit=limit,
4447
order_by=order_by,

services/director-v2/src/simcore_service_director_v2/modules/db/repositories/comp_runs.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@ async def list_for_user__only_latest_iterations(
195195
*,
196196
product_name: str,
197197
user_id: UserID,
198+
# filters
199+
filter_only_running: bool,
198200
# pagination
199201
offset: int,
200202
limit: int,
@@ -229,6 +231,16 @@ async def list_for_user__only_latest_iterations(
229231
& (
230232
comp_runs.c.metadata["product_name"].astext == product_name
231233
) # <-- NOTE: We might create a separate column for this for fast retrieval
234+
& (
235+
comp_runs.c.result.in_(
236+
[
237+
RUNNING_STATE_TO_DB[item]
238+
for item in RunningState.list_running_states()
239+
]
240+
)
241+
)
242+
if filter_only_running
243+
else True
232244
)
233245
.group_by(comp_runs.c.project_uuid)
234246
.subquery("latest_runs")

services/web/server/src/simcore_service_webserver/api/v0/openapi.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2567,6 +2567,13 @@ paths:
25672567
type: integer
25682568
default: 0
25692569
title: Offset
2570+
- name: filter_only_running
2571+
in: query
2572+
required: false
2573+
schema:
2574+
type: boolean
2575+
default: false
2576+
title: Filter Only Running
25702577
responses:
25712578
'200':
25722579
description: Successful Response
@@ -9102,6 +9109,12 @@ components:
91029109
format: date-time
91039110
- type: 'null'
91049111
title: Endedat
9112+
rootProjectName:
9113+
type: string
9114+
title: Rootprojectname
9115+
projectCustomMetadata:
9116+
type: object
9117+
title: Projectcustommetadata
91059118
type: object
91069119
required:
91079120
- projectUuid
@@ -9111,6 +9124,8 @@ components:
91119124
- submittedAt
91129125
- startedAt
91139126
- endedAt
9127+
- rootProjectName
9128+
- projectCustomMetadata
91149129
title: ComputationRunRestGet
91159130
ComputationStart:
91169131
properties:

services/web/server/src/simcore_service_webserver/director_v2/_computations_service.py

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from decimal import Decimal
22

33
from aiohttp import web
4-
from models_library.api_schemas_directorv2.comp_runs import (
5-
ComputationRunRpcGetPage,
4+
from models_library.computations import (
5+
ComputationRunWithAttributes,
6+
ComputationTaskWithAttributes,
67
)
7-
from models_library.computations import ComputationTaskWithAttributes
88
from models_library.products import ProductName
99
from models_library.projects import ProjectID
1010
from models_library.rest_ordering import OrderBy
@@ -17,36 +17,86 @@
1717
from servicelib.utils import limited_gather
1818

1919
from ..products.products_service import is_product_billable
20-
from ..projects.api import check_user_project_permission, get_project_dict_legacy
20+
from ..projects.api import (
21+
batch_get_project_name,
22+
check_user_project_permission,
23+
get_project_dict_legacy,
24+
)
25+
from ..projects.projects_metadata_service import (
26+
get_project_custom_metadata_or_empty_dict,
27+
)
2128
from ..rabbitmq import get_rabbitmq_rpc_client
2229

2330

2431
async def list_computations_latest_iteration(
2532
app: web.Application,
2633
product_name: ProductName,
2734
user_id: UserID,
35+
# filters
36+
filter_only_running: bool, # noqa: FBT001
2837
# pagination
2938
offset: int,
3039
limit: NonNegativeInt,
3140
# ordering
3241
order_by: OrderBy,
33-
) -> ComputationRunRpcGetPage:
42+
) -> tuple[int, list[ComputationRunWithAttributes]]:
3443
"""Returns the list of computations (only latest iterations)"""
3544
rpc_client = get_rabbitmq_rpc_client(app)
3645
_runs_get = await computations.list_computations_latest_iteration_page(
3746
rpc_client,
3847
product_name=product_name,
3948
user_id=user_id,
49+
filter_only_running=filter_only_running,
4050
offset=offset,
4151
limit=limit,
4252
order_by=order_by,
4353
)
4454

45-
# NOTE: MD: Get project metadata
46-
# NOTE: MD: Get Root project name
47-
assert _runs_get # nosec
55+
# Get projects metadata (NOTE: MD: can be improved with a single batch call)
56+
_projects_metadata = await limited_gather(
57+
*[
58+
get_project_custom_metadata_or_empty_dict(
59+
app, project_uuid=item.project_uuid
60+
)
61+
for item in _runs_get.items
62+
],
63+
limit=20,
64+
)
65+
66+
# Get Root project names
67+
_projects_root_uuids: list[ProjectID] = []
68+
for item in _runs_get.items:
69+
if (
70+
prj_root_id := item.info.get("project_metadata", {}).get(
71+
"root_parent_project_id", None
72+
)
73+
) is not None:
74+
_projects_root_uuids.append(ProjectID(prj_root_id))
75+
else:
76+
_projects_root_uuids.append(item.project_uuid)
77+
78+
_projects_root_names = await batch_get_project_name(
79+
app, projects_uuids=_projects_root_uuids
80+
)
81+
82+
_computational_runs_output = [
83+
ComputationRunWithAttributes(
84+
project_uuid=item.project_uuid,
85+
iteration=item.iteration,
86+
state=item.state,
87+
info=item.info,
88+
submitted_at=item.submitted_at,
89+
started_at=item.started_at,
90+
ended_at=item.ended_at,
91+
root_project_name=project_name,
92+
project_custom_metadata=project_metadata,
93+
)
94+
for item, project_metadata, project_name in zip(
95+
_runs_get.items, _projects_metadata, _projects_root_names, strict=True
96+
)
97+
]
4898

49-
return _runs_get
99+
return _runs_get.total, _computational_runs_output
50100

51101

52102
async def list_computations_latest_iteration_tasks(

services/web/server/src/simcore_service_webserver/director_v2/_controller/computations_rest.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,12 @@ async def list_computations_latest_iteration(request: web.Request) -> web.Respon
5353
ComputationRunListQueryParams, request
5454
)
5555

56-
_get = await _computations_service.list_computations_latest_iteration(
56+
total, items = await _computations_service.list_computations_latest_iteration(
5757
request.app,
5858
product_name=req_ctx.product_name,
5959
user_id=req_ctx.user_id,
60+
# filters
61+
filter_only_running=query_params.filter_only_running,
6062
# pagination
6163
offset=query_params.offset,
6264
limit=query_params.limit,
@@ -67,10 +69,10 @@ async def list_computations_latest_iteration(request: web.Request) -> web.Respon
6769
page = Page[ComputationRunRestGet].model_validate(
6870
paginate_data(
6971
chunk=[
70-
ComputationRunRestGet.model_validate(task, from_attributes=True)
71-
for task in _get.items
72+
ComputationRunRestGet.model_validate(run, from_attributes=True)
73+
for run in items
7274
],
73-
total=_get.total,
75+
total=total,
7476
limit=query_params.limit,
7577
offset=query_params.offset,
7678
request_url=request.url,

services/web/server/src/simcore_service_webserver/projects/_controller/metadata_rest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ async def get_project_metadata(request: web.Request) -> web.Response:
4747
req_ctx = RequestContext.model_validate(request)
4848
path_params = parse_request_path_parameters_as(ProjectPathParams, request)
4949

50-
custom_metadata = await _metadata_service.get_project_custom_metadata(
50+
custom_metadata = await _metadata_service.get_project_custom_metadata_for_user(
5151
request.app, user_id=req_ctx.user_id, project_uuid=path_params.project_id
5252
)
5353

0 commit comments

Comments
 (0)